摘录自man find
:
-print0
正确;打印完整文件名在标准输出上,后跟一个空字符(而不是 -print 使用的换行符)。这样,处理 find 输出的程序就可以正确解释包含换行符或其他类型空格的文件名。此选项对应于 xargs 的 -0 选项。
因此,如果(例如)您想要查找并删除目录中早于最新 10 个的文件,则可以使用(信用@pLumo):
find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | xargs -0 gio trash
但是,在执行此命令之前,您如何计算即将被删除的文件的数量?
答案1
使用grep
,它可以处理由空字符分隔的行:
find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | grep -zc .
从man grep
:
-z, --null-data
Treat input and output data as sequences of lines, each terminated by a zero byte
(the ASCII NUL character) instead of a newline. Like the -Z or --null option, this
option can be used with commands like sort -z to process arbitrary file names.
因此,如果(例如)您想要查找并删除目录中早于最新 10 个的文件,则可以使用...
不,你不能。find
的输出不能保证按照创建、修改、访问或任何其他顺序进行(除非有一个按 排序-depth
,但这与此无关)。
你需要类似这样的东西:
find . -maxdepth 1 -type f -printf '%T@ %p\0' | sort -Vrz | sed -z '1,10d; s/^[[:digit:].]* //'
它使用修改时间(使用 打印为 unix 时间戳)%T@
,并按此进行排序,使用-V
版本排序作为一般浮点排序的代理,最后使用 删除时间戳sed
。
答案2
保留同一行并打印删除文件后的文件数量:
find . -maxdepth 1 -type f -print0 | sort -rz | sed -z 1,10d | xargs -0 bash -c 'gio trash $*;echo $# files trashed'
或者您可以独立计算行数。只需返回正常的行尾(print
而不是print0
删除-z
)。
find . -maxdepth 1 -type f -print | sort -r | sed 1,10d | wc -l
答案3
创建一个按降序排列文件的索引数组;最新文件在索引 0 上,或者ls -rt
按升序排列文件。
$ eval "a=($(ls -t --quoting-style=shell-escape))"
从第 n 个文件打印到末尾:
(使用具有偏移量的降序数组|--|xxxx|
将防止循环意外吃掉您的文件)。
$ printf %s\\n "${a[@]:10}"
从开始到第 n 个文件打印:
$ printf %s\\n "${a[@]:0:10}" # or "${a[@]::10}"
^ ^
offset length
从头开始打印第 n 个文件:
$ printf %s\\n "${a[@]:5:1}"
打印倒数第 n 个文件:
$ printf %s\\n "${a[@]:(-5):1}"
打印以空字符结尾的文件列表:
$ printf %s\\0 "${a[@]:10}" | xargs -0 -n 1
脚本示例如何在循环中使用它;
#!/bin/bash
eval "a=($(ls -t --quoting-style=shell-escape))"
for b in "${a[@]:10}"; do
ls "$b"
done