英文:
How to convert values of recurring elements row by row to columns?
问题
I receive an output of some script that gives rows containing element and its value.
And there are only 3 elements that repeated with different values.
Want to convert them to columns with element name as column name and then values per column.
我收到一个脚本的输出,其中包含包含元素及其值的行。
只有3个元素,但值不同。
希望将它们转换为以元素名称为列名,然后是每列的值。
I have an output that gathers some server info and put it in file output.txt
that looks like following:
我有一个输出,汇总了一些服务器信息,并将其放入名为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
So using google I handled it and with the following commands put all values into columns named real user and sys as following:
所以,我使用谷歌处理了它,并使用以下命令将所有值放入名为real 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}'
so the output looks like this one:
所以输出如下所示:
real user sys
0m0.537s 0m0.077s 0m0.082s
0m0.512s 0m0.076s 0m0.083s
0m0.498s 0m0.072s 0m0.087s
So I have 2 questions.
- How to make column name to fit the column?
- There should be a way to perform all this ugly stuff using one-liner. Does anyone have this one-liner?
所以我有两个问题。
- 如何使列名适应列的宽度?
- 有没有一种方法可以使用单行命令执行所有这些繁琐的操作?有人有这个单行命令吗?
英文:
I receive an output of some script that gives rows containing element and it's value.
And there are only 3 elements that repeated with different values.
Want to convert them to columns with element name as column name and then values per column.
I have an output that gathers some server info and put it in file output.txt
that looks like following:
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
So using google I handled it and with the following commands put all values into columns named real user and sys as following:
$ 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}'
so the output looks like this one:
real user sys
0m0.537s 0m0.077s 0m0.082s
0m0.512s 0m0.076s 0m0.083s
0m0.498s 0m0.072s 0m0.087s
So I have 2 questions.
- How to make column name to fit the column?
- There should be a way to perform all this ugly stuff using one-liner. Does anyone have this one-liner?
答案1
得分: 1
以下是已翻译好的内容:
你可以使用 awk
轻松完成这个任务。
脚本假设示例中始终有完整的3行组,并且sys
是最后一行。
或者更短一些的方式:
如果你想要一行命令,去掉换行和空格。
输出结果(以制表符分隔):
如何对齐列标题与数据取决于你的需求。
基于这个假设,修复这个问题的一种方法是在打印标题时使用两个制表符:
或者你可以使用 printf
来控制字段宽度。
打印:
英文:
You can easily do this with awk
.
The script assumes there are always complete groups of 3 lines as in the example and that sys
is the last.
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
or shorter
awk 'BEGIN { print "real\tuser\tsys" }
/^r/ { r=$2 }
/^u/ { u=$2 }
/^s/ { s=$2; print r "\t" u "\t" s }' output.txt
If you want a one-liner, remove line breaks and spaces.
awk 'BEGIN{print "real\tuser\tsys"}/^r/{r=$2}/^u/{u=$2}/^s/{s=$2;print r"\t"u"\t"s}' output.txt
Resulting output (tab-separated):
real user sys
0m0.537s 0m0.077s 0m0.082s
0m0.512s 0m0.076s 0m0.083s
0m0.498s 0m0.072s 0m0.087s
How to align the column headings with the data depends on what you need.
Since the string length of the data is 8 characters while the headings are 3 or 4 characters long, the TAB positions (with default TAB width 8) characters are different.
Based on this assumption, one way to fix this is to use two tabs when printing the headings:
BEGIN { print "real\t\tuser\t\tsys" }
Or you could use printf
with field with.
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
prints
real user sys
0m0.537s 0m0.077s 0m0.082s
0m0.512s 0m0.076s 0m0.083s
0m0.498s 0m0.072s 0m0.087s
答案2
得分: 0
You can format any text into columns like this:
$ 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
Depending on the version of "column" you have (most Linux should be fine), you can probably solve the whole problem like this:
$ 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
The "sed" removes the first column, the "xargs" groups the values into threes, and the "column" aligns everything and adds the headers.
英文:
You can format any text into columns like this:
$ 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
Depending what version of "column" you have (most Linux should be fine), you can probably solve the whole problem like this:
$ 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
The "sed" removes the first column, the "xargs" groups the values into threes, and the "column" aligns everything and adds the headers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论