sin*_*ium 3 command-line bash scripts
我想删除多个分辨率低于 228x228 的图像。为此,我编写了这个 shell 脚本:
#!/bin/bash
for i in $( ls ); do
if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
then
rm $i
fi
done
Run Code Online (Sandbox Code Playgroud)
由于某些原因,我在运行它时得到了这个输出:
./del.sh: line 4: [640: command not found
./del.sh: line 4: [550: command not found
./del.sh: line 4: [315: command not found
...
Run Code Online (Sandbox Code Playgroud)
你能告诉我这个脚本有什么问题以及如何解决它。
谢谢你。
编辑:即使在括号后添加空格后,我仍然遇到错误。这是由于使用了<而不是-lt并且已修复。现在没有错误。
Per*_*uck 11
这里有一些问题:首先,[…]测试中的表达式需要周围有空格(陷阱 #10),其次比较<不适用于[…]测试(陷阱 #7)。您要么需要-lt(小于)要么使用[[…]],这是一种bashism。此外,for应该替换循环(陷阱 #1)。
所以:
for i in ./*; do
if [ -e "$i" ]; then
if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
then
rm -- "$i"
fi
fi
done
Run Code Online (Sandbox Code Playgroud)
您可能还想避免调用identify两次来获取两个维度(陷阱 #58),而是只调用一次并让它打印一个字符串,准备用作 shell 语法中的变量赋值。
如果我们写
identify -format "width=%w height=%h" "$i"
Run Code Online (Sandbox Code Playgroud)
它会打印类似width=50 heigth=250. 当我们使用eval该字符串时,我们只用一次调用就设置了两个变量,条件可以写为:
eval "$(identify -format "width=%w height=%h" "$i")"
if [ $width -lt 228 ] && [ $height -lt 228 ];
then
rm -- "$i"
fi
Run Code Online (Sandbox Code Playgroud)
另请参阅:常见的 bash 陷阱。
我会使用findwith-exec和,而不是循环-delete:
find . -maxdepth 1 -type f \
-exec sh -c '
[ $(identify -format "%w" "$1") -lt 228 ] &&
[ $(identify -format "%h" "$1") -lt 228 ]' _ {} \; \
-delete -print
Run Code Online (Sandbox Code Playgroud)
这也将打印被删除的文件,-print如果您不想要,可以删除。