bash删除脚本不起作用

我有一个bash脚本,应该不是.avi,.mp4和.mkv的所有文件。

这是我试过的:

#!/bin/bash FILES=$(find /home/mattia/test/ -type f -name '*.*') for f in $FILES do ext=${f#*.} echo $ext if [[ "$ext" != "mp4" || "$ext" != "mkv" || "$ext" != "avi" ]]; then rm -f $f echo deleted fi done 

但是这个脚本删除了所有的文件。

除了改变||&& ,脚本是脆弱的,例如,如果任何文件包含空格,它将无法正常工作。 一般来说,将find的输出存储在循环变量中是不安全的,所以应该避免这种做法。

无论如何,你不需要循环, find可以自己做这一切,更安全:

 find /home/mattia/test/ -type f ! \( -name '*.mp4' -o -name '*.mkv' -o -name '*.avi' \) -print -delete 

请注意,而不是! ,你可以使用更直观的-not ,但请记住,它不是POSIX兼容。

这是合乎逻辑的

 [[ "$ext" != "mp4" || "$ext" != "mkv" || "$ext" != "avi" ]] 

总是如此。 例如:如果文件名是movie.avi"$ext" != "mp4"将是真的,因此完整的if总是为真。

一如往常,有很多方法可以解决这个问题。 雅诺斯find ; 另一种选择是:

 find /find /home/mattia/test/ -type f -name '*.*'home/mattia/test/ -type f -name '*.*' | egrep -v '.mp4$|.mkv$|.avi$' | xargs rm 

或者,在你的循环中:

 #!/bin/bash FILES=$(find /home/mattia/test/ -type f -name '*.*') for f in $FILES do ext=${f#*.} echo $ext case "$ext" in (mp4) echo "Keeping $f" ;; (mkv) echo "Not deleting $f" ;; (avi) echo "Holding on to $f" ;; (*) rm -f "$f" echo "deleted $f" ;; esac done 

(只要你的文件名没有空格就应该工作)

或者整理if条件

 [[ ! ( "$ext" = "mp4" || "$ext" = "mkv" || "$ext" = "avi" ) ]]