如何使用awk和grep将命令输出解析为列

时间:2022-03-31 19:30:33

I have the output of pkginfo -l that looks like below

我有pkginfo -l的输出,如下所示

A: aaa1  
B: bbb1
C: ccc1
D: ddd1

A: aaa2  
B: bbb2
C: ccc2
D: ddd2

A: aaa3  
C: ccc3
D: ddd3

I want this output translated into columns such that it looks like below

我希望将此输出转换为列,使其看起来如下所示

A        B        C         D
aaa1     bbb1     ccc1      ddd1
aaa2     bbb2     ccc2      ddd2
aaa3              ccc3      ddd3

Currenlty I am finding names of packages individually using pkginfo and then running pkginfo -l pkgname to get the output and parse on it to display info in columns but each invocation of pkginfo -l is time consuming.

Currenlty我使用pkginfo单独找到包的名称,然后运行pkginfo -l pkgname来获取输出并解析它以在列中显示信息,但每次调用pkginfo -l都很耗时。

Is there an easier way to do in ksh with grep/awk where I can store teh output of pkginfo -l into a file and then use grep/awk on that to achieve the intended output?

使用grep / awk在ksh中有更简单的方法吗?我可以将pkginfo -l的输出存储到文件中,然后使用grep / awk来实现预期的输出?

2 个解决方案

#1


1  

Here is some to help you get started.

这里有一些可以帮助您入门。

awk -F": " 'BEGIN {c=0} NF{a[$1 FS c]=$2;b[$1];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

#2


1  

This might be what you want depending on the answers to the question I left in a comment:

根据我在评论中留下的问题的答案,这可能是您想要的:

$ 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

Consider this:

考虑一下:

$ 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

Is that the desired output? If not, what's wrong with it?

这是所需的输出吗?如果没有,它有什么问题?

#1


1  

Here is some to help you get started.

这里有一些可以帮助您入门。

awk -F": " 'BEGIN {c=0} NF{a[$1 FS c]=$2;b[$1];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

#2


1  

This might be what you want depending on the answers to the question I left in a comment:

根据我在评论中留下的问题的答案,这可能是您想要的:

$ 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

Consider this:

考虑一下:

$ 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

Is that the desired output? If not, what's wrong with it?

这是所需的输出吗?如果没有,它有什么问题?