如果我运行该命令,du -ah | sort -nr
是否可以让它显示输出中的哪一行是文件以及哪个文件夹?类似于命令ls -l
显示哪个是文件和文件夹,前面有d
和。-
答案1
这是有可能的,但需要借助其他命令。具体来说,这里我们使用 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
当然,这种方法稍微有缺陷,因为它似乎无法处理包含空格的文件名(仍在努力改进它)
另外,我们还可以使用find
命令来查找所有文件,然后运行file
和du
命令通过标志执行我们的命令-exec
,但这看起来有点丑陋(请参阅编辑历史)。但是,我们可以使用find
的 -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
显然这里f
是针对普通文件,而d
是针对目录。find
有关标志和文件类型字母的更多信息,请参阅 的手册
答案2
正如 Serg 所说,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' _
、-0
和选项告诉、-z
和使用 ASCII nul 作为分隔符。-0
du
sort
xargs
然后,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/
因为我使用了ls --color
,所以我也得到了很好的颜色输出: