如何使用 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

这是期望的输出吗?如果不是,那有什么问题?