【发布时间】:2020-02-06 23:15:37
【问题描述】:
对于学校作业,我试图递归地遍历目录和子目录以总结文件的大小。我遇到的问题是构造:
for f in ./* ./.*; do
# summing logic here
done
卡在f = ./. 上它可以很好地进入每个目录,但是一旦它进入一个完全处理的目录,在最后一个文件之后,f 被设置为./.。我有逻辑来检查f 是否是一个目录,它确实如此,然后进入f 来处理它。并永远循环在那里。
我尝试包含代码来检查字符串f 是否匹配“./.” 或”./..”,但它永远不会评估为真。我犯了什么错误?
主要问题:为什么if [[ "$f" != "./." ]] || [[ "$f" != "./.." ]]; then 不起作用,我该怎么做才能获得相同的结果?此外,如果我尝试for f in ./* ./.* ; do echo $f done 之类的东西,我看不到./. 和./.. 被打印出来。 f 如何在我的脚本中设置为这些值?
我见过类似问题的答案,涉及 bash-builtin shopt,但我使用 zsh 而学校的测试服务器使用 csh。我真的希望有一些与平台无关的东西。
小提示:由于代码现在是这样,因此分配已完成。我们只需要对当前工作目录中文件的大小求和,不包括子目录。我对使脚本递归感到好奇,我只是为了满足我的兴趣而做这部分。感谢您的帮助。
#!bin/bash
total_size=0
get_file_size() {
stat --printf="%s" "$1"
}
add_file_sizes() {
for f in ./* ./.*; do
echo "Currently processing: $f"
if [ -d "$f" ] && [ "$1" == -r ]; then
echo "$f is a directory"
if [ "$f" != "./." ] || [ "$f" != "./.." ]; then
echo "$f is not ./. or ./.."
cd "$f"
pwd
add_file_sizes "-r"
echo "$total_size"
cd ../
fi
fi
if [ ! -d "$f" ]; then
echo "$f is not a directory"
total_size=$((total_size + $(get_file_size "$f")))
echo "$total_size"
fi
done
}
add_file_sizes $1
echo "$total_size"
编辑:这是一些输出:
Currently processing: list_size.sh
list_size.sh is not a directory
625
Currently processing: output.txt
output.txt is not a directory
759
Currently processing: test_dir
test_dir is a directory
test_dir is not ./. or ./..
/home/joe/dev/csc60/test_dir
Currently processing: file1
file1 is not a directory
759
Currently processing: file2
file2 is not a directory
759
Currently processing: test_subdir
test_subdir is a directory
test_subdir is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
Currently processing: ./.
./. is a directory
./. is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
759
编辑 2:调整了初始 for 循环并普遍改进了脚本以响应答案中的建议。
当我将 for 循环更改为 for f in * .[!.]* 时的输出:
Currently processing: list_size.sh
list_size.sh is not a directory
578
Currently processing: list_size_tweaked.sh
list_size_tweaked.sh is not a directory
1156
Currently processing: output_tweaked.txt
output_tweaked.txt is not a directory
1394
Currently processing: output.txt
output.txt is not a directory
1394
Currently processing: test_dir
test_dir is a directory
test_dir is not ./. or ./..
/home/joe/dev/csc60/test_dir
Currently processing: file1
file1 is not a directory
1394
Currently processing: file2
file2 is not a directory
1394
Currently processing: test_subdir
test_subdir is a directory
test_subdir is not ./. or ./..
/home/joe/dev/csc60/test_dir/test_subdir
Currently processing: file3
file3 is not a directory
1394
Currently processing: .[!.]*
.[!.]* is not a directory
1394
stat: cannot stat '.[!.]*': No such file or directory
./list_size_tweaked.sh: line 25: total_size + : syntax error: operand expected (error token is "+ ")
7670
这似乎是因为目录中没有点文件,所以 glob 没有展开。
【问题讨论】:
-
find是“正确”的方式 -
当我进行初步研究时,那是一篇非常有用的帖子。
shopt几乎肯定会解决我遇到的问题,但 shopt 是内置的 bash,我使用 zsh,教授的测试机器使用 csh。我可以看看是否有 csh 等价物,但理想情况下,我正在寻找与平台无关的东西。 -
我认为
.[!.]*应该适用于任何posix shell。 posix 2.13.3 Patterns Used for Filename Expansion。 dot 匹配一个点,[!.]匹配除点以外的任何内容。 -
另外,刚刚阅读完
find的联机帮助页,您能否再给我一些关于您的意思的信息?