如果我运行该命令du -ah | sort -nr
,是否可以使其显示输出中的哪一行是文件和哪个文件夹?类似于命令的东西ls -l
显示了前面有d
和 的文件和文件夹-
。
这是可能的,但并非没有另一个命令的帮助。具体来说,这里我们使用的是 GNU awk(这很重要,所以请检查您的 awk 版本)
$ du -ah | sort -nr | awk '{usage=$1; $1="";cmd="file "$0;cmd |& getline type;print usage,type ;close(cmd)}'
24K .: directory
4.0K ./testdir: directory
4.0K ./out.txt: ASCII text
4.0K ./3.txt: ASCII text
4.0K ./2.txt: ASCII text
4.0K ./1.txt: ASCII text
Run Code Online (Sandbox Code Playgroud)
当然,这种方法略有缺陷,因为它似乎因包含空格的文件名而失败(仍在努力改进它)
作为替代方案,我们也可以使用find
命令来查找所有文件并运行file
和du
命令通过-exec
标志来进行我们的投标,但这看起来有点难看(请参阅编辑历史记录)。然而,我们可以使用find
's -printf
标志来打印文件类型和%y
格式以获得更漂亮的输出。
$ find -mindepth 1 -printf "%y\t" -exec du "{}" \; | sort -rn
f 4 ./out.txt
f 4 ./3.txt
f 4 ./2.txt
f 4 ./1.txt
f 0 ./with space.txt
d 4 ./testdir
Run Code Online (Sandbox Code Playgroud)
显然这里f
是用于常规文件,d
用于目录。有关find
标志和文件类型字母的更多信息,请参阅手册
正如塞尔格所说,不能自己du
做到这一点。要安全地处理文件名,最好的方法是用 ASCII 空字符 ( \0
)将它们分开,并且du
可以做到这一点。所以,使用,随着sort
和xargs
'能力处理空分隔输入:
du -0ah |
sort -zh |
xargs -0 sh -c 'for i; do s=${i%%[[:space:]]*};f=${i#*[[:space:]]}; echo "$s" "$(ls --color -dF "$f")"; done' _
Run Code Online (Sandbox Code Playgroud)
的-0
,-z
而-0
选择告诉du
,sort
并xargs
使用ASCII NUL作为分隔符。
然后,s=${i%[[:space:]]*}
获取行的开头直到空格(即大小),并f=${i#*[[:space:]]}
获取其他所有内容(文件名)。然后我们可以ls
打印带有装饰的文件名。
例子:
$ du -0ah Screenshots | sort -zh | xargs -0 sh -c 'for i; do s=${i%%[[:space:]]*};f=${i#*[[:space:]]}; echo "$s" "$(ls --color -dF "$f")"; done' _
512 Screenshots/desktop.ini*
264K Screenshots/Screenshot (1).png*
269K Screenshots/
Run Code Online (Sandbox Code Playgroud)
因为我使用了ls --color
,我也得到了漂亮的颜色输出: