在 ubuntu 终端中的目录中删除 n 个最大的文件

delete n largest files in a directory in ubuntu terminal

我想删除一个目录中的 n 个(在我们的例子中是 2 个)最大的文件。

files=$(ls -S | head -2)
rm $files

这不起作用,因为文件名中有 space 和各种特殊字符。我用这个 ls -xS | head -2 | xargs rm 得到了类似的结果。我想应该转义文件名中的所有特殊字符,但有多种类型的特殊字符。虽然可行,但没想到会这么复杂。 我使用 -Q 选项来引用文件名,但我仍然得到同样的错误。

Downloads > files=$(ls -SQ | head -1)
Downloads > echo $files
"[ www.UsaBit.com ] - Little Children 2006 720p BRRip x264-PLAYNOW.mp4"
Downloads > rm $files
rm: cannot remove ‘"[’: No such file or directory
rm: cannot remove ‘www.UsaBit.com’: No such file or directory
rm: cannot remove ‘]’: No such file or directory
rm: cannot remove ‘-’: No such file or directory
rm: cannot remove ‘Little’: No such file or directory
rm: cannot remove ‘Children’: No such file or directory
rm: cannot remove ‘2006’: No such file or directory
rm: cannot remove ‘720p’: No such file or directory
rm: cannot remove ‘BRRip’: No such file or directory
rm: cannot remove ‘x264-PLAYNOW.mp4"’: No such file or directory

如果您的 ls 支持 -Q 选项,它将用双引号(和反斜杠双引号)引用所有名称。

您不能将这样的输出直接用作 rm 的参数,因为分词不会考虑引号。可以使用eval强制分词:

eval rm $(ls -Q | head -2)

小心使用! eval 是危险的,它可以运行 将数据变成运行ning 你无法控制的代码。我的测试显示 ls -Q 将换行符转换为 \n,这不会被解释为双引号中的换行符!

效果很好,即使在 这种 情况下使用 eval 碰巧是安全的,最好养成避免它的习惯如果有其他选择。
解析 ls.

的输出也是如此

一般建议是:

就是说,有时 ls 提供了如此多的便利,以至于 很难使用它,就像这种情况一样这里:ls -S 方便地按文件大小排序(降序);手工制作相同的逻辑是不平凡的。

你为解析 ls 输出付出的代价是 嵌入 换行符 (\n) 的文件名将不会被处理正确(choroba 的回答也是如此)。也就是说,这样的文件名 很少在现实世界中引起关注

虽然 xargs 默认情况下对其输入行应用分词 - 这就是处理带有嵌入空格的文件名失败的原因 - 它 可以将每个输入行识别为不同的原样参数(注意ls,当不输出到终端时,默认在其 自己的 行输出每个文件名):

GNU xargs(用于大多数 Linux 发行版):

ls -S | head -2 | xargs -d $'\n' rm       # $'\n' requires bash, ksh, or zsh

-d $'\n 告诉 xargs 在将参数传递给 rm 时将每个输入行 视为一个整体 作为一个单独的参数。

BSD/macOS xargs(也适用于 GNU xargs):

xargs 实现不支持 -d 选项,但它支持 -0 将输入按 NUL(0x0 字节)拆分为参数。因此,需要中间 tr 命令将 \n 转换为 NUL:

ls -S | head -2 | tr '\n' '[=11=]' | xargs -0 rm