将列中的值转换为行

时间:2016-07-07 05:55:54

标签: unix text awk

我有一个文本文件,其中包含以下格式的数据。我想为第一列中的每个值创建一行。

0-09935152                          RC=3       CC=2   L=10-11
                   M=1
                   BNT=4
0-09935153                   F=31                     L=11
                   M=1
0-09935154                   F=31                     L=11
                   M=1
0-09935155                   F=31                     L=11
                   M=1
0-09935156                   F=31                     L=11
                   M=1
0-09935157                   F=31                     L=11
                   M=1
0-09935158                   F=31                     L=11
                   M=1
0-09935159                   F=31                     L=11
                   M=1
0-0993516                    F=31                     L=11
                   M=1
0-0993517                    F=31                     L=11
                   M=1
0-0993518                    F=31                     L=11
                   M=1
0-0993519                    F=0               CC=2
                   M=1

我想将所有相应的值拉成一行。预期的输出就像

Code|M|F|CC|L|BNT|RC
0-09935152|1||2|10-11|4|3
0-09935153|1|31||11|||

我正在尝试使用awk来解析文本文件。我只能隔离列但无法继续进行。

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

awk -f script.awk文件

<强> script.awk

BEGIN{RS="[ \n]";OFS="|";print "Code","M","F","CC","L","BNT","RC"} #print headers
length > 1 {size=split($0,t,"=")} #split values by "="
size==2{a[t[1]]=t[2]} #non-code values
size==1 && flag {print code,a["M"],a["F"],a["CC"],a["L"],a["BNT"],a["RC"];delete a;code=$0} #print values for each code switch
size==1 && !flag{flag++;code=$0} #skip first
{delete t;size=0} #clear data 
END{print code,a["M"],a["F"],a["CC"],a["L"],a["BNT"],a["RC"]} # print last value

<强>输出

Code|M|F|CC|L|BNT|RC
0-09935152|1||2|10-11|4|3
0-09935153|1|31||11||
0-09935154|1|31||11||
0-09935155|1|31||11||
0-09935156|1|31||11||
0-09935157|1|31||11||
0-09935158|1|31||11||
0-09935159|1|31||11||
0-0993516|1|31||11||
0-0993517|1|31||11||
0-0993518|1|31||11||
0-0993519|1|0|2|||

答案 1 :(得分:0)

BEGIN {
    RS="( +|\n)" # set the record separator to put every piece of data on a separate row for split
    OFS="|"      # # below: initialize the header
    arr[0]="Code"; arr["M"]="M"; arr["F"]="F"; arr["CC"]="CC"; arr["L"]="L"; arr["BNT"]="BNT"; arr["RC"]="RC"
}
/^[0-9]+-/ {     # print arr when new code starts
    print arr[0],arr["M"],arr["F"],arr["CC"],arr["L"],arr["BNT"],arr["RC"];
    delete arr;  # empty previous values from arr
    arr[0]=$0
}
{
    split($0,brr,"[=]"); # split from "=" to another array
    arr[brr[1]]=brr[2]   # first part is the index, latter is the value
}
END { # print the last line, too bad you can't "/^[0-9]+-/ || END {..."
print arr[0],arr["M"],arr["F"],arr["CC"],arr["L"],arr["BNT"],arr["RC"];
}

$ awk -f test.awk test.in
Code|M|F|CC|L|BNT|RC
0-09935152|1||2|10-11|4|3
0-09935153|1|31||11||
0-09935154|1|31||11||
[...]