在 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
.
的输出也是如此
一般建议是:
避免在您无法控制的输入上使用 eval
,因为它会导致执行任意命令。
Do not parse ls
output; if possible, use pathname expansion (globbing).
就是说,有时 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
我想删除一个目录中的 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
.
一般建议是:
避免在您无法控制的输入上使用
eval
,因为它会导致执行任意命令。Do not parse
ls
output; if possible, use pathname expansion (globbing).
就是说,有时 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