用于比较文件的Bash脚本

Ast*_*rum 3 sorting bash

我有一个包含大量旧照片的文件夹,其中包含许多重复照片.手动排序需要很长时间,所以我想借此机会使用bash.

现在我有代码:

#!/bin/bash

directory="~/Desktop/Test/*"
for file in ${directory};
do
    for filex in ${directory}:
    do
        if [ $( diff {$file} {$filex} ) == 0 ]
        then
            mv ${filex} ~/Desktop
            break
        fi
    done
done 
Run Code Online (Sandbox Code Playgroud)

并获得退出代码:

diff: {~/Desktop/Test/*}: No such file or directory
diff: {~/Desktop/Test/*:}: No such file or directory
File_compare: line 8: [: ==: unary operator expected
Run Code Online (Sandbox Code Playgroud)

我已经尝试修改我在网上找到的工作代码,但似乎总是吐出一些这样的错误.我猜这是嵌套for循环的问题?

另外,为什么看起来有不同的方法来调用变量?我见过使用过的例子${file}, "$file", and "${file}".

Jon*_*ler 6

你有{}错误的地方:

if [ $( diff {$file} {$filex} ) == 0 ]
Run Code Online (Sandbox Code Playgroud)

他们应该在:

if [ $( diff ${file} ${filex} ) == 0 ]
Run Code Online (Sandbox Code Playgroud)

(虽然大括号现在是可选的),但你应该允许文件名中的空格:

if [ $( diff "${file}" "${filex}" ) == 0 ]
Run Code Online (Sandbox Code Playgroud)

现在它根本无法正常工作,因为当diff发现没有差异时,它不会产生任何输出(并且您会收到错误,因为==操作员在其左侧并不期望任何内容).您可以通过双引用$(…)(if [ "$( diff … )" == "" ])中的值来修复它,但您应该直接测试退出状态diff:

if diff "${file}" "${filex}"
then : no difference
else : there is a difference
fi
Run Code Online (Sandbox Code Playgroud)

并且可能用于比较您应该使用的图像cmp(在静音模式下)而不是diff:

if cmp -s "$file" "$filex"
then : no difference
else : there is a difference
fi
Run Code Online (Sandbox Code Playgroud)


Gor*_*son 5

除了 Jonathan Leffler 指出的问题:

directory="~/Desktop/Test/*"
for file in ${directory};
Run Code Online (Sandbox Code Playgroud)

~并且*不会在双引号内展开;*当您使用不带引号的变量时,它将被扩展,但由于~不会,它会在实际名为“~”的目录(不是您的主目录)下寻找文件,它不会找到任何匹配项。此外,正如乔纳森指出的那样,使用${directory}不带双引号的变量(如)会使您遇到包含空格或其他一些元字符的文件名的麻烦。更好的方法是不要将通配符放在变量中,在引用变量时使用它,变量用双引号括起来,*在它们外面:

directory=~/"Desktop/Test"
for file in "${directory}"/*;
Run Code Online (Sandbox Code Playgroud)

哦,还有一个注意事项:mv在脚本中使用时,最好使用它mv -i以避免意外覆盖另一个同名文件。

并且:使用shellcheck.net对您的代码进行完整性检查并指出常见错误。