过去几周我花了很多时间在这里发帖。我终于认为我更接近于学习bash但是我的代码有一个问题我不能为我的生活弄清楚为什么它不会运行。我可以在终端中运行每一行并返回一个结果,但由于某种原因,当我指向它运行时,它将什么都不做。我得到一个语法错误:单词意外(期待"做")。
#!/bin/bash
image="/Home/Desktop/epubs/images"
for f in $(ls "$image"*.jpg); do
fsize=$(stat --printf= '%s' "$f");
if [ "$fsize" -eq "40318" ]; then
echo "$(basename $f)" >> results.txt
fi
done
我缺少什么?
答案 0 :(得分:1)
问题可能在于行尾。确保您的脚本文件具有unix行结尾,而不是Windows结尾。
另外,请勿迭代ls
的输出。在shell中使用globbing:
for f in "$file"/*.jpg ; do
答案 1 :(得分:0)
我将如何做到这一点。
#!/bin/bash -e
image="/Home/Desktop/epubs/images"
(cd "$image"
for f in *.jpg; do
let fsize=$(stat -c %s "$f")
if (( fsize == 40318 )); then
echo "$f"
fi
done) >results.txt
-e
表示如果出现任何问题,脚本将退出(例如,无法进入目录)。当你对这种行为感到满意时,可以节省大量的错误检查。
括号表示cd
命令位于子shell中;周围的脚本(包括重定向到results.txt
)仍然在你开始的任何目录中。
现在我们在目录中,我们只能查找*.jpg
,没有目录前缀,也无需在任何内容上调用basename
。
使用let
和(( == ))
将大小值视为数字而不是字符串,因此我们不会因stat
选择格式化的方式而被任何困难所绊倒值。
我们只是将整个循环的输出重定向到结果文件中,而不是每次都附加;它效率更高。如果您要保留results.txt
中的现有内容,则可以将>
更改回>>
,但将其保留在整个循环中仍然比打开文件并在每次迭代时附加到它。
答案 2 :(得分:0)
您的for循环似乎缺少要迭代的值列表:
image="/Home/Desktop/epubs/images"
for f in $(ls "$image"*.jpg); do
由于$image
不以/结尾,因此ls
命令会扩展为
for f in $(ls /Home/Desktop/epubs/images*.jpg); do
可能导致
for f in ; do
导致语法错误。最简单的解决方法是
for f in $(ls "$image"/*.jpg); do
但你应该听取其他答案中的建议并跳过ls
:
for f in "$image"/*.jpg; do