用于删除文件的 shell 脚本不起作用

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 陷阱


pLu*_*umo 6

我会使用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如果您不想要,可以删除。