对具有不同列数的行使用awk

对具有不同列数的行使用awk,awk,Awk,我在终端上打印了以下信息,您可以看到第一行和第二行的列数 Strms Blocks Compressed Uncompressed Ratio Check Filename 1 1 2,526.9 MiB 317.1 GiB 0.008 CRC64 rar.stadium.trace.xz 因此,如果我使用awk'{print$3”\t“$4}',我将得到 Compressed Uncompressed 2,526.9 MiB 这不是我想要

我在终端上打印了以下信息,您可以看到第一行和第二行的列数

Strms  Blocks   Compressed Uncompressed  Ratio  Check   Filename
    1       1  2,526.9 MiB    317.1 GiB  0.008  CRC64   rar.stadium.trace.xz
因此,如果我使用
awk'{print$3”\t“$4}'
,我将得到

Compressed  Uncompressed
2,526.9 MiB

这不是我想要的。有什么想法吗?

如果您想使用GNU awk,可以解析第一行以确定
字段宽度:

awk '(NR==1){ for(i=1;i<=NF;++i) {match($0," *"$i); f=f" "RLENGTH};
              FIELDWIDTHS=f; $0=$0}
     {print $3,$4}'
如果您希望它是人类可读的格式,可以在awk中使用此函数:

function tohuman(size, t,u,s) {
    split( "B KiB MiB GiB TiB PiB EiB ZiB YiB" , u, " ");
    t=size; s=1; while( t>1024 ){ t/=1024; s++ }
    return sprintf("%6.1f %s", t, u[s]) }

如果要使用GNU awk,可以解析第一行以确定
字段宽度

awk '(NR==1){ for(i=1;i<=NF;++i) {match($0," *"$i); f=f" "RLENGTH};
              FIELDWIDTHS=f; $0=$0}
     {print $3,$4}'
如果您希望它是人类可读的格式,可以在awk中使用此函数:

function tohuman(size, t,u,s) {
    split( "B KiB MiB GiB TiB PiB EiB ZiB YiB" , u, " ");
    t=size; s=1; while( t>1024 ){ t/=1024; s++ }
    return sprintf("%6.1f %s", t, u[s]) }

使用
FIELDWIDTHS
参数和
gnu awk
设置每个字段的宽度,如下所示:

xz -l t.xz | awk '{print $3"\t"$4}' FIELDWIDTHS="5 8 13 13 7 7 99"
   Compressed    Uncompressed
     79.7 MiB       553.9 MiB
  2,526.9 MiB       317.1 GiB
编辑:最后一个字段设置为99,以便在需要时处理长文件名
Edit2:更好地处理字段的空间和长度

Edit3:
FIELDWIDTHS=“5 8 13 13 7*”
可以使用。

使用
FIELDWIDTHS
参数和
gnu awk
设置每个字段的宽度,如下所示:

xz -l t.xz | awk '{print $3"\t"$4}' FIELDWIDTHS="5 8 13 13 7 7 99"
   Compressed    Uncompressed
     79.7 MiB       553.9 MiB
  2,526.9 MiB       317.1 GiB
编辑:最后一个字段设置为99,以便在需要时处理长文件名
Edit2:更好地处理字段的空间和长度


Edit3:
FIELDWIDTHS=“5 8 13 13 7*”
可以使用。

是您的列分隔符
选项卡
?它是
xz-l
的输出。我认为它使用了空格。从手册页上看:“对于机器可读的输出,应该使用
--robot--list
。”如果您的表在字段之间使用
'
(空格),并且字段中也有空格,那么您将遇到问题。实际的数据文件是什么样子的?(您也可以选择在
awk
中使用“固定宽度”字段)如果它是固定长度,您可以使用
cut-c16-39
作为列分隔符
选项卡
?它是
xz-l
的输出。我认为它使用了空格。从手册页上看:“对于机器可读的输出,应该使用
--robot--list
。”如果您的表在字段之间使用
'
(空格),并且字段中也有空格,那么您将遇到问题。实际的数据文件是什么样子的?(您也可以选择在
awk
中使用“固定宽度”字段)查看它是否为固定长度,您可以使用
cut-c16-39
这很好,但它以字节为单位打印大小,而不是自动以MB或GB值为单位。使用动态字段宽度是个好主意。缩短一些,删除
()
和一个
awk'NR==1{对于(i=1;iUps),如果文件名长于label
Filename
,则会剪切文件名。可以通过将最后一个字段宽度设置为99来解决。
awk'NR==1{对于(i=1;如果/当列标题字符串包含regexp元字符或是另一个元字符的子字符串时,该方法将失败。您可以使用另一个gawk特定的功能,FPAT:
BEGIN{FPAT=“\\s*\\s+”}NR==1{for(i=1;i@EdMorton我没有更新我的答案,但引用了你的评论。非常有效的观点和极好的修复!这很好,但它以字节为单位打印大小,而不是自动打印MB或GB值。使用动态字段宽度的好主意。缩短一些,删除
()
,并删除一个
awk'NR==1{for(i=1;iUps,如果文件名长于label
Filename
,则会剪切文件名。可以通过将最后一个字段宽度设置为99来解决此问题。
awk'NR==1{for(i=1;如果/当列标题字符串包含regexp元字符或是另一个元字符的子字符串时,该方法将失败。您可以使用另一个gawk特定的功能,FPAT:
BEGIN{FPAT=“\\s*\\s+”}NR==1{for(i=1;i@EdMorton我没有更新我的答案,但引用了你的评论。非常有效的观点和极好的修复!它不应该是
FIELDWIDTHS=“7 8…
?(注意
2
的位置)Fieldwidth不是一个常数。不是,但必须足够小,以不干扰下一个字段的最大值。使用
9
,将截断
2526.9 MiB
中的
2
。@mahmood更新为符合结尾对齐和长文件名。您应该提到,这需要GNU awk用于Fieldwidth。此外,使用更新的vegawk的rsion您可以使用
*
作为FIELDWIDTHS中的最终值来表示行中剩余的内容,而不必选择一些数字,如
99
。它不应该是
FIELDWIDTHS=“7 8…”
?(注意
2
的位置)Fieldwidth不是一个常数。不是,但必须足够小,以不干扰下一个字段的最大值。使用
9
,将截断
2526.9 MiB
中的
2
。@mahmood更新为符合结尾对齐和长文件名。您应该提到,这需要GNU awk用于Fieldwidth。此外,使用更新的vegawk的rsion您可以使用
*
作为FIELDWIDTHS中的最终值来表示行中剩余的内容,而不必选择一些数字,如
99