是否可以使用单个命令删除所有符合某个模式的文件?
file_name_1294132_rest_of_file
rm \*(less than 1294132)\*
答案1
在最简单的情况下,如果您有合理的文件名,不包含新行等奇怪字符,您可以这样做:
rm "$(ls | gawk -F_ '$3<1294132')"
有很多原因为什么应该避免解析ls
,所以这里有一个解决方法:
for f in file_*; do
printf %s "$f" | perl -anF_ -e 'unlink() if $F[2]<1294132';
done
答案2
由于“rm”命令,我假设 UNIX/Linux。
所有文件都位于同一目录中吗?如果不是,事情就会变得非常复杂。
如果是,那么您可能遇到了一个目录中文件太多的问题,应该考虑一下您的布局。
虽然速度比较慢,但这个方法还是可行的:
seq 1 1294131 | xargs -i{} echo rm file_name_{}_rest_of_file
(当然,当您想运行真正的 rm 时,请删除 echo)为了加快速度,我会对不需要比较的文件进行 globs 处理:
rm file_name_[1-9]_rest_of_file
rm file_name_[1-9][0-9]_rest_of_file
rm file_name_[1-9][0-9][0-9]_rest_of_file
rm file_name_[1-9][0-9][0-9][0-9]_rest_of_file
等等,直到你的 shell 抱怨命令行长度。
另一个快速而肮脏的方法是:
find . -name 'file_name_*_rest_of_file' | sort -n > /tmp/files.txt
编辑 file.txt 以删除应该删除的文件不是被删除
< /tmp/files/txt xargs rm
您还可以编写一个脚本,将文件名标记为组件,提取“计数”,进行比较,然后删除或传递文件。但这可能比上述任何一种方法都要花费更长的时间。
答案3
你可以把这些都放在一行上(用';'s)并将其称为一个命令
for f in file_name_*_rest_of_file
do
n=${f//[^0-9]}
if [[ -n $n && $n -lt 22 ]]
then
echo del $f
fi
done
有点长
for f in file_name_*_rest_of_file;do; n=${f//[^0-9]}; if [[ -n $n && $n -lt 22 ]]; then echo del $f; fi;done
${f//[^0-9]} 是一种 bashism,可以用
nn=${f#file_name_}
n=${nn%_rest_of_file}
或者
n=`echo $f | tr -C -d '[0-9]'`