我想删除所有文件,但是我在列表中删除了一个文件。让我们为了论证而说这些文件是在一个数组中。该数组仅包含文件的最后三位数字,不包含扩展名。所有文件都是扩展名jpg。这就是我一直在努力做的事情。文件名采用GEDC1227.JPG
的形式pics=(227 222 231 248 252 253 255 272 274 278)
for line in *; do
for j in $pics[@]; do
[[ ${line:5:3} == $j ]] && break
done
rm $line
done
我知道有更简单的方法可以实现这一目标;但是,我有点好奇,为什么我的算法不起作用。我认为是因为每次都进入rm $行,而且当测试条件为真时我没有找到绕过该行的方法(对于我不想删除的文件)
答案 0 :(得分:4)
你需要继续两次,即恢复外循环的下一次迭代:
pics=(227 222 231 248 252 253 255 272 274 278)
for line in *; do
for j in "${pics[@]}"; do
[[ ${line:5:3} == "$j" ]] && continue 2
done
rm -- "$line"
done
${pics[@]}
添加引号。不是必需的,但在元素扩展时防止单词拆分是一种很好的做法。==
的第二个参数,以防止将其解释为glob模式。--
添加到rm
,以防止尝试以-
作为选项读取文件并导致rm
错误。此备选解决方案也可能适用但需要测试:
shopt -s extglob
shopt -s nullglob
echo rm -- ?????!(227|222|231|248|252|253|255|272|274|278)*
如果发现正确,请删除echo
。
continue
:
继续:继续[n]
恢复for,while或者循环。
恢复封闭FOR,WHILE或UNTIL循环的下一次迭代。 如果指定了N,则恢复第N个封闭循环。
答案 1 :(得分:0)
我也会考虑在没有循环的情况下这样做。
如果目录中有许多文件,可以使这样的东西并行运行并且不会阻塞(就像一个glob)。
pics=( 227 222 231 248 252 253 255 272 274 278 )
# convert the array to a regex that matches GEDC.227\.JPG$|GEDC.222\.JPG$|...
keep="$( echo "GEDC.${pics[@]}\\.JPG$" | sed -e 's: :\\.JPG$|GEDC.:g' )"
find -type f -iname GEDC*.jpg \
| egrep -v "$keep" \
| xargs rm