格式化du命令输出

时间:2017-12-13 23:57:15

标签: shell formatting zsh du

有没有办法格式化(在shell命令链中)du -s -k *

的以下输出
287720  crm-cc
21500   crm-mvh
40360   elasticsearch-5.1.2
293292  electron-quick-start
44636   hexagon
193572  jpk
132 knights
209860  pink-panther
1722104 popc
4   server-config.txt
45392   sigb-backend
47468   test
58904   um-report
164156  zeus

以下列方式:

1,763,434,496 popc
  300,331,008 electron-quick-start
  294,625,280 crm-cc
  214,896,640 pink-panther
  198,217,728 jpk
  168,095,744 zeus
   60,317,696 um-report
   48,607,232 test
   46,481,408 sigb-backend
   45,707,264 hexagon
   41,328,640 elasticsearch-5.1.2
   22,016,000 crm-mvh
      135,168 knights
        4,096 server-config.txt

我的意思是:

  • 按文件/目录的大小按降序排序。
  • 每隔三个字符插入一个千位分隔符 右。
  • 插入前导空格以使大小与右侧对齐

I have implemented this in PHP但我希望有一个更通用的解决方案(不是每个基于Linux的操作系统都安装了PHP解释器。)

如果相关,我大部分时间都在使用zsh,因此解决方案可以限制在此shell中。

2 个答案:

答案 0 :(得分:4)

例如,让我们考虑一下包含这些文件的目录:

$ du -sk *
12488   big.log
200     big.pdf
4       f1
2441412 output.txt
160660  program.zip
4       smallfile
4       some.txt

根据需要重新格式化du

$ du -sk * | sort -rn | sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta' | awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}'
 2,441,412 output.txt
   160,660 program.zip
    12,488 big.log
       200 big.pdf
         4 some.txt
         4 smallfile
         4 f1

注意:即使文件名包含空格,此方法也适用。

为方便起见,

Shell功能

由于上面的内容很多,所以让我们创建一个shell函数:

$ dusk() { du -sk "$@" | sort -rn | sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta' | awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}';}

我们可以使用shell函数如下:

$ dusk *
 2,441,412 output.txt
   160,660 program.zip
    12,488 big.log
       200 big.pdf
         4 some.txt
         4 smallfile
         4 f1

如何运作

  • du -sk *

    这是我们的du命令。

  • sort -rn

    这是按相反的顺序进行数字排序,以便最大的文件首先出现。

  • sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta'

    这会将逗号放在我们想要的地方。

  • awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}';}

    这正确地证明了这些数字。

多行版本

对于那些喜欢将命令分散在多行中的人:

du -sk * |
    sort -rn |
    sed -E ':a; s/([[:digit:]]+)([[:digit:]]{3})/\1,\2/; ta' |
    awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}'

与Mac OSX / BSD的兼容性

试试这个并查看它是否适用于OSX:

$ echo 1234567890 | sed -E -e :a -e 's/([[:digit:]]+)([[:digit:]]{3})/\1,\2/' -e ta 
1,234,567,890

如果可行,那么让我们修改完整的命令:

du -sk * | sort -rn | sed -E -e :a -e 's/([[:digit:]]+)([[:digit:]]{3})/\1,\2/' -e ta  | awk -F'\t' '{printf "%10s %s\n",$1,substr($0,length($1)+2)}'

答案 1 :(得分:4)

使用sort和GNU awk(file中的输出):

$ sort -nr file | awk '{printf "%'\''d %s\n",$1,$2}'
1,722,104 popc
293,292 electron-quick-start
287,720 crm-cc
...

如果要右对齐第一个字段,则需要为printf提供第一个字段的宽度,例如:

$ sort -nr file | awk '{printf "%'\''9d %s\n",$1,$2}'
1,722,104 popc
  293,292 electron-quick-start
  287,720 crm-cc

9是带有逗号的$1的长度,您可以使用逗号计算:length($1)+(length($1)-1)/3表示最长$1,这是第一个,所以:

$ sort -nr file | 
  awk 'NR==1 { len=length($1) + (length($1)-1)/3 }
  { printf "%'\''" len "d %s\n",$1,$2 }'
1,722,104 popc
  293,292 electron-quick-start
  287,720 crm-cc