unix 如何将循环元素的值逐行转换为列?

wnvonmuf  于 2023-05-17  发布在  Unix
关注(0)|答案(2)|浏览(202)

我收到一些脚本的输出,它给出了包含元素及其值的行。并且只有3个元素以不同的值重复。希望将它们转换为以元素名作为列名的列,然后是每列的值。
我有一个输出,它收集了一些服务器信息,并将其放入文件output.txt中,如下所示:

real    0m0.537s
user    0m0.077s
sys 0m0.082s

real    0m0.512s
user    0m0.076s
sys 0m0.083s

real    0m0.498s
user    0m0.072s
sys 0m0.087s

所以我使用google处理了它,并使用以下命令将所有值放入名为真实的user和sys的列中,如下所示:

$ sed -i '/^$/d' output.txt
$ awk -F " " '{ print $2 }' output.txt > output2.txt
$ paste -d'\t' - - - < output2.txt | awk 'BEGIN { print "real\tuser\tsys"} {print $0}'

所以输出看起来像这样:

real    user    sys
0m0.537s    0m0.077s    0m0.082s
0m0.512s    0m0.076s    0m0.083s
0m0.498s    0m0.072s    0m0.087s

所以我有两个问题。
1.如何使列名适合该列?
1.应该有一种方法来执行所有这些丑陋的东西使用一行程序。有没有人有这本单行本?

bqucvtff

bqucvtff1#

您可以使用awk轻松完成此操作。
脚本假设总是有3行的完整组,如示例中所示,sys是最后一行。

awk 'BEGIN { print "real\tuser\tsys" }
$1=="real" { r=$2 }
$1=="user" { u=$2 }
$1=="sys" { s=$2; print r "\t" u "\t" s }' output.txt

或更短

awk 'BEGIN { print "real\tuser\tsys" }
/^r/ { r=$2 }
/^u/ { u=$2 }
/^s/ { s=$2; print r "\t" u "\t" s }' output.txt

如果需要一行代码,请删除换行符和空格。

awk 'BEGIN{print "real\tuser\tsys"}/^r/{r=$2}/^u/{u=$2}/^s/{s=$2;print r"\t"u"\t"s}' output.txt

结果输出(制表符分隔):

real    user    sys
0m0.537s        0m0.077s        0m0.082s
0m0.512s        0m0.076s        0m0.083s
0m0.498s        0m0.072s        0m0.087s

如何将列标题与数据对齐取决于您的需要。
由于数据的字符串长度为8个字符,而标题的长度为3或4个字符,因此TAB位置(默认TAB宽度为8)的字符是不同的。
基于这个假设,解决这个问题的一种方法是在打印标题时使用两个选项卡:

BEGIN { print "real\t\tuser\t\tsys" }

或者你可以使用printf和field。

awk 'function myprint(a, b, c) {
    printf("%-10s %-10s %-10s\n", a, b, c)
}
BEGIN { myprint("real", "user", "sys") }
/^r/ { r=$2 }
/^u/ { u=$2 }
/^s/ { s=$2; myprint(r, u, s) }' output.txt

印刷品

real       user       sys
0m0.537s   0m0.077s   0m0.082s
0m0.512s   0m0.076s   0m0.083s
0m0.498s   0m0.072s   0m0.087s
odopli94

odopli942#

您可以将任何文本格式化为列,如下所示:

$ column -t file.txt
real      user      sys
0m0.537s  0m0.077s  0m0.082s
0m0.512s  0m0.076s  0m0.083s
0m0.498s  0m0.072s  0m0.087s

根据你的“column”版本(大多数Linux应该没问题),你可以像这样解决整个问题:

$ sed 's/^\S*//' output.txt | xargs -n3 echo | column -t -N real,user,sys
real      user      sys
0m0.537s  0m0.077s  0m0.082s
0m0.512s  0m0.076s  0m0.083s
0m0.498s  0m0.072s  0m0.087s

“sed”删除第一列,“xargs”将值分成三组,“column”对齐所有内容并添加标题。

相关问题