如何使用 awk 和 grep 将命令的输出解析为列
How do I parse the output of a command into columns using awk and grep
我有 pkginfo -l
的输出,如下所示
A: aaa1
B: bbb1
C: ccc1
D: ddd1
A: aaa2
B: bbb2
C: ccc2
D: ddd2
A: aaa3
C: ccc3
D: ddd3
我希望将此输出转换为列,如下所示
A B C D
aaa1 bbb1 ccc1 ddd1
aaa2 bbb2 ccc2 ddd2
aaa3 ccc3 ddd3
Currenlty 我正在使用 pkginfo
然后 运行 pkginfo -l pkgname
分别查找包的名称以获取输出并对其进行解析以在列中显示信息,但每次调用 pkginfo -l
很费时间。
在使用 grep/awk 的 ksh 中有没有更简单的方法,我可以将 pkginfo -l
的输出存储到一个文件中,然后在该文件上使用 grep/awk 来实现预期的输出?
这里有一些可以帮助您入门的内容。
awk -F": " 'BEGIN {c=0} NF{a[ FS c]=;b[];next} {c++} END {for (i=0;i<=c;i++) {for (j in b) printf "%s\t",a[j FS i];print ""}}' file
aaa1 bbb1 ccc1 ddd1
aaa2 bbb2 ccc2 ddd2
aaa3 ccc3 ddd3
这可能是您想要的,具体取决于我在评论中留下的问题的答案:
$ cat tst.awk
BEGIN { RS=""; FS="\n"; OFS="\t" }
{
for (i=1;i<=NF;i++) {
split($i,a,/: /)
name = a[1]
value = a[2]
if ( !seen[name]++ ) {
colNname2nr[name] = ++numCols
colNr2name[numCols] = name
}
colNr = colNname2nr[name]
cell[NR,colNr] = value
}
next
}
END{
for (colNr=1;colNr<=numCols;colNr++) {
printf "%s%s", colNr2name[colNr], (colNr<numCols?OFS:ORS)
}
for (rowNr=1;rowNr<=NR;rowNr++) {
for (colNr=1;colNr<=numCols;colNr++) {
printf "%s%s", cell[rowNr,colNr], (colNr<numCols?OFS:ORS)
}
}
}
$ awk -f tst.awk file
A B C D
aaa1 bbb1 ccc1 ddd1
aaa2 bbb2 ccc2 ddd2
aaa3 ccc3 ddd3
考虑一下:
$ cat file
A: aaa1
C: ccc1
D: ddd1
A: aaa2
B: bbb2
C: ccc2
D: ddd2
A: aaa3
B: bbb3
C: ccc3
D: ddd3
$ awk -f tst.awk file
A C D B
aaa1 ccc1 ddd1
aaa2 ccc2 ddd2 bbb2
aaa3 ccc3 ddd3 bbb3
这是期望的输出吗?如果不是,那有什么问题?
我有 pkginfo -l
的输出,如下所示
A: aaa1
B: bbb1
C: ccc1
D: ddd1
A: aaa2
B: bbb2
C: ccc2
D: ddd2
A: aaa3
C: ccc3
D: ddd3
我希望将此输出转换为列,如下所示
A B C D
aaa1 bbb1 ccc1 ddd1
aaa2 bbb2 ccc2 ddd2
aaa3 ccc3 ddd3
Currenlty 我正在使用 pkginfo
然后 运行 pkginfo -l pkgname
分别查找包的名称以获取输出并对其进行解析以在列中显示信息,但每次调用 pkginfo -l
很费时间。
在使用 grep/awk 的 ksh 中有没有更简单的方法,我可以将 pkginfo -l
的输出存储到一个文件中,然后在该文件上使用 grep/awk 来实现预期的输出?
这里有一些可以帮助您入门的内容。
awk -F": " 'BEGIN {c=0} NF{a[ FS c]=;b[];next} {c++} END {for (i=0;i<=c;i++) {for (j in b) printf "%s\t",a[j FS i];print ""}}' file
aaa1 bbb1 ccc1 ddd1
aaa2 bbb2 ccc2 ddd2
aaa3 ccc3 ddd3
这可能是您想要的,具体取决于我在评论中留下的问题的答案:
$ cat tst.awk
BEGIN { RS=""; FS="\n"; OFS="\t" }
{
for (i=1;i<=NF;i++) {
split($i,a,/: /)
name = a[1]
value = a[2]
if ( !seen[name]++ ) {
colNname2nr[name] = ++numCols
colNr2name[numCols] = name
}
colNr = colNname2nr[name]
cell[NR,colNr] = value
}
next
}
END{
for (colNr=1;colNr<=numCols;colNr++) {
printf "%s%s", colNr2name[colNr], (colNr<numCols?OFS:ORS)
}
for (rowNr=1;rowNr<=NR;rowNr++) {
for (colNr=1;colNr<=numCols;colNr++) {
printf "%s%s", cell[rowNr,colNr], (colNr<numCols?OFS:ORS)
}
}
}
$ awk -f tst.awk file
A B C D
aaa1 bbb1 ccc1 ddd1
aaa2 bbb2 ccc2 ddd2
aaa3 ccc3 ddd3
考虑一下:
$ cat file
A: aaa1
C: ccc1
D: ddd1
A: aaa2
B: bbb2
C: ccc2
D: ddd2
A: aaa3
B: bbb3
C: ccc3
D: ddd3
$ awk -f tst.awk file
A C D B
aaa1 ccc1 ddd1
aaa2 ccc2 ddd2 bbb2
aaa3 ccc3 ddd3 bbb3
这是期望的输出吗?如果不是,那有什么问题?