我正在尝试编写一个相当简单的脚本,但找不到跳过某些文件的合理方法。
我想按照给定的顺序列出所有文件。如果该列表包含超过(比方说)10 个文件,我想删除文件 11-n 但保留前(或最后)10 个文件。
/TLDR:在管道进入下一个命令之前,如何在 find/ls/whatever 结果中跳过固定数量的文件
我想按名称对所有文件(具有给定模式)进行排序,如果超过 10 个,则删除它们。
答案1
使用zsh
, 模式
*(.[11,-1])
将匹配当前目录中常规文件的所有名称(不是目录名称等),按名称对它们进行排序(默认排序顺序),并返回除前十个名称之外的所有名称。
测试:
$ touch file-{01..20}
$ ls
file-01 file-03 file-05 file-07 file-09 file-11 file-13 file-15 file-17 file-19
file-02 file-04 file-06 file-08 file-10 file-12 file-14 file-16 file-18 file-20
$ printf '%s\n' *(.[11,-1])
file-11
file-12
file-13
file-14
file-15
file-16
file-17
file-18
file-19
file-20
你愿意吗删除这些文件:
$ rm *(.[11,-1])
$ ls
file-01 file-02 file-03 file-04 file-05 file-06 file-07 file-08 file-09 file-10
请注意,这需要该zsh
shell 和另一个 shell 一样,bash
无法理解所使用的特殊类型的通配模式。
从其他 shell 中,您可以使用
zsh -c 'rm *(.[11,-1])'
你bash
可以做类似的事情
names=( * )
printf '%s\n' "${names[@]:10}"
列出您可能想要删除的文件名,但不能保证列出的名称是常规文件的名称,很可能还有目录名称。所以你可能想循环:
for name in *; do
if [ -f "$name" ]; then
files+=( "$name" )
fi
done
printf '%s\n' "${files[@]:10}"
这还将获取指向常规文件的符号链接的名称。
要删除这些,请使用rm "${files[@]:10}"
.
与所有删除数据的操作一样,您将测试任何解决方案副本在实际运行之前获取真实数据。
答案2
您向我们提供了关于您正在尝试执行的操作的非常模糊的描述,因此这个答案可能同样模糊,但是:
head
并tail
为此目的而设计。
如果您想忽略除前十个结果之外的所有内容,请使用:
head -n 10
并忽略除最后十个结果之外的所有内容,请使用:
tail -n 10
注意:仅当您的结果由换行符分隔时,这些才有效。