【问题标题】:Adding titles to file data while moving position based on pattern matches (SED or AWK) while preserving counts在基于模式匹配(SED 或 AWK)移动位置的同时向文件数据添加标题,同时保留计数
【发布时间】:2021-07-29 00:52:29
【问题描述】:

我目前正在努力处理一个查询,在该查询中,我需要从具有 2 列或更多列的文件中获取数据,并且不仅要提取数据,还要根据给定的数据为每一列添加标题。这是文件数据的示例。

--

test_AA.98
test_AA.99+
8 35=Apples
16 35=Pears

test_AA.100
14 35=Apples
12 35=Pears
test_AB.101-
15 35=Banannas

-- 如果我 cat 和 awk 第一列 - cat testfile | awk '{ print $1 }' - 结果

test_AA.98
test_AA.99+
8
16


test_AA.100
14
12

test_AB.101-
15

-- 如果我 cat 和 wak 第二列 - cat testfile | awk '{ print $2 }' - 结果

35=Apples
35=Pears



35=Apples
35=Oranges


35=Banannas

-- 谁能提供一个解决方案,我可以根据模式匹配(test*)将标题标题添加到我的数据到 $1 位置,匹配 35=*,移动到 $2 位置,同时保持计数和值在地方?我想要的结果。

Suppliers,  Red=35=Apples, Green=35=Pears, Yellow=35=Banannas
            
test_AA.98, 0,  0,  0
test_AA.99+,    8,  16, 0
test_AA.100,    14, 12, 0
test_AB.101-,   0,  0,  15

我只找到了一些添加标题的解决方案,但还没有想办法在标题下放置正确的值。

sed '1iSuppliers, Red=35=Apples, Green=35=Pears, Yellow=35=Banannas' testfile
Suppliers, 35=Apples, 35=Pears, 35=Banannas
test_AA.98
test_AA.99+
8 35=Apples
16 35=Pears


test_AA.100
14 35=Apples
12 35=Oranges

test_AB.101-
15 35=Banannas

非常感谢!!

【问题讨论】:

    标签: awk sed formatting counting


    【解决方案1】:

    这里有一些让你开始的东西。

    使用 awk 脚本

    # set column separator
    # r[] - output columns
    BEGIN { OFS=", "; r[0]="Suppliers" }
    
    # first pass:
    
    # find name from $2, store for later lookup
    # t[] - test if $2 value already seen
    # c[] - lookup table for column index by name
    FNR==NR && NF==2 && !t[$2]++ { r[++n]=$2; c[$2]=n }
    FNR==NR { next }
    
    # second pass:
    
    # line with single field ends previous block
    NF==1 {
        # print row (or header if first line)
        s=r[0]; for(i=1;i<=n;i++) s = s OFS r[i]; print s
    
        # reset columns for subsequent lines
        r[0]=$1; for(i=1;i<=n;i++) r[i]=0
    
        next
    }
    
    # insert value into appropriate output column
    NF==2 { r[c[$2]]=$1 }
    
    # output the final line
    END { s=r[0]; for(i=1;i<=n;i++) s = s OFS r[i]; print s }
    

    调用为:

    awk -f script testfile testfile
    

    使用您的示例输入,这会产生:

    Suppliers, 35=Apples, 35=Pears, 35=Banannas
    test_AA.98, 0, 0, 0
    test_AA.99+, 8, 16, 0
    test_AA.100, 14, 12, 0
    test_AB.101-, 0, 0, 15
    

    如果您已经知道标头可以采用的所有值,并且您想为它们添加前缀,或者以特定顺序显示它们,您可以在 BEGIN 中适当地初始化 r[]c[]。然后删除FNR==NR ... 行,并以awk -f script testfile 调用。

    【讨论】:

    • 嗨,Jhnc.. 他们将有许多供应商和 35=* 的许多不同条目,具体取决于白天/晚上发生的情况。但我非常感谢您的回复,稍后会测试您的解决方案。
    【解决方案2】:
    $ cat tst.awk
    BEGIN {
        col2tag[++numCols] = "Suppliers"
        OFS = ",\t"
    }
    NF==1 {
        rowNr = ++numRows
        colNr = 1
    }
    NF==2 {
        if ( $2 in tag2col ) {
            colNr = tag2col[$2]
        }
        else {
            colNr = ++numCols
            col2tag[colNr] = $2
            tag2col[$2] = colNr
        }
    }
    NF {
        vals[rowNr,colNr] = $1
    }
    END {
        for (colNr=1; colNr<=numCols; colNr++) {
            printf "%s%s", col2tag[colNr], (colNr<numCols ? OFS : ORS)
        }
        for (rowNr=1; rowNr<=numRows; rowNr++) {
            for (colNr=1; colNr<=numCols; colNr++) {
                val = ( (rowNr,colNr) in vals ? vals[rowNr,colNr] : 0 )
                printf "%s%s", val, (colNr<numCols ? OFS : ORS)
            }
        }
    }
    

    $ awk -f tst.awk file
    Suppliers,      35=Apples,      35=Pears,       35=Banannas
    test_AA.98,     0,      0,      0
    test_AA.99+,    8,      16,     0
    test_AA.100,    14,     12,     0
    test_AB.101-,   0,      0,      15
    

    $ awk -f tst.awk file | column -s$'\t' -t
    Suppliers,     35=Apples,  35=Pears,  35=Banannas
    test_AA.98,    0,          0,         0
    test_AA.99+,   8,          16,        0
    test_AA.100,   14,         12,        0
    test_AB.101-,  0,          0,         15
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多