问题:如何删除除最新3之外的所有文件?
find最新的3个文件很简单:
ls -t | head -3
但我需要find除最新的3个文件以外的所有文件。 我该怎么做,如何在同一行删除这些文件,而不必为此循环?
我正在使用Debian Wheezy和bash脚本。
这将列出除最新三个以外的所有文件:
ls -t | tail -n +4
这将删除这些文件:
ls -t | tail -n +4 | xargs rm --
这也将列出dotfiles:
ls -At | tail -n +4
并用dotfiles删除:
ls -At | tail -n +4 | xargs rm --
但要小心:当文件名包含有趣的字符如换行符或空格时,解析ls
可能会很危险。 如果您确定您的文件名不包含有趣的字符,那么解析ls
是相当安全的,如果它是一次性脚本,则更是如此。
如果您正在开发一个重复使用的脚本,那么您绝对不应该解析ls
的输出,并使用下面描述的方法: http : //mywiki.wooledge.org/ParsingLs
以下看起来有点复杂,但是非常谨慎是正确的,即使是不寻常的或故意的恶意文件名。 不幸的是,它需要GNU工具:
count=0 while IFS= read -r -d ' ' && IFS= read -r -d '' filename; do (( ++count > 3 )) && printf '%s\0' "$filename" done < <(find . -maxdepth 1 -type f -printf '%T@ %P\0' | sort -g -z) \ | xargs -0 rm -f --
解释这是如何工作的:
<mtime> <filename><NUL>
。 sort -g -z
基于第一列(时间)用NUL分隔的行做一般的(浮点数,而不是整数)数值排序。 while
循环中的第一次read
剥离了mtime( sort
完成后不再需要)。 while
循环中的第二次read
读取文件名(运行直到NUL)。 xargs -0
然后把这个文件名附加到它正在收集的argv列表中以调用rm
。 ls -t | tail -n +4 | xargs -I {} rm {}
如果你想要一个班轮
这使用find
而不是与Schwartzian变换 ls
。
find . -type f -printf '%T@\t%p\n' | sort -t $'\t' -g | tail -3 | cut -d $'\t' -f 2-
find
搜索文件,并用时间戳来装饰它们,并使用制表符分隔这两个值。 sort
分割tabulator的输入,并执行一个普通的数字排序,正确地排序浮点数。 tail
应该是明显的, cut
undecorates。
装饰的问题一般是找到一个合适的分隔符,而不是输入文件名的一部分。 这个答案使用NULL字符。
不要使用ls -t
因为对于可能包含空格或特殊的glob字符的文件名是不安全的。
您可以使用所有基于gnu
的实用程序来删除当前目录中的所有3个最新文件:
find . -maxdepth 1 -type f -printf '%T@\t%p\0' | sort -z -nrk1 | tail -z -n +4 | cut -z -f2- | xargs -0 rm -f --