awk ライナーは入力データを目的の出力にフォーマットします。

awk ライナーは入力データを目的の出力にフォーマットします。

入力ファイルです。


    QSUM HEADER                          STOCK   DATE    TIME
206  CC-USER REJECT SENT             TNPPP   200322  104914600

TI         JPS        TNN        LTNN       PP         JP
                      8          6          0          1

AA         NS                                          CPOODE
4          899599991119

TYPE       AI
12         18

QSUM HEADER                          STOCK   DATE    TIME
206  CC-USER REJECT SENT             TNPPP   200322  115844000

TI         JPS        TNN        LTNN       PP         JP
                      8          6          0          1

AA         NS                                          CPOODE
4          899599991555

TYPE       AI
12         18
QSUM HEADER                          STOCK   DATE    TIME
103  SUITE FAIL, SUBTRACT FAILURE   TPNRM   200318  031124100

TI         PNC        TNN        PP         JP         AA
2          1499       177        123        1          4

NS                                          FLAG       
999999999999                                ORIGIN

TI         CPO


QSUM HEADER                          STOCK   DATE    TIME
103  SUITE FAIL, SUBTRACT FAILURE   TPNRM   200318  031124200

TI         PNC        TNN        PP         JP         AA
2          1499       177        123        1          4

NS                                          FLAG       
999999999999                                ORIGIN

TI         CPO

次の出力が必要です


    QSUM HEADER                          STOCK   DATE    TIME       TI     PNC       JPS        TNN        LTNN       PP         JP AA         NS                     FLAG                     OPCODE TYPE       AI TI CPO
206  CC-USER REJECT SENT             TNPPP   200322  104914600                               8          6          0          1 4          899599991119                                       12         18
206  CC-USER REJECT SENT             TNPPP   200322  115844000                               8          6          0          1 4          899599991555                                       12         18
103  SUITE FAIL, SUBTRACT FAILURE   TPNRM   200318  031124100    2     1499                 177                   123         1 4          999999999999          ORIGIN
103  SUITE FAIL, SUBTRACT FAILURE   TPNRM   200318  031124200    2     1499                 177                   123         1 4          999999999999          ORIGIN

私は次のサンプルawkライナーを試しました


    awk 'BEGIN{print ("QSUM HEADER                          STOCK   DATE    TIME       TI     PNC       JPS        TNN        LTNN       PP         JP AA         NS                     FLAG                     OPCODE TYPE       AI TI CPO")}

/^[0-9]/{print a["o"] " " a["p"] " " a["q"]
              ;delete a}

             /^[0-9]/{a["o"]=$0
              next}
             /TNN/{getline
                    a["p"]=$0
                      next}
              /NS/{getline
                   a["q"]=$0
                   next}
                   END
                {print a["o"] " " a["p"] " " a["q"];}'

各ヘッダー型のパターンを一致させた後、次の行を配置する必要があります。この結果を達成するための他の良い選択肢。このコードは私にとってうまくフィットしますが、ここで問題は、ヘッダーと同じくらい長くなるということです。

ベストアンサー1

FPATand にはGNU awkを使用します(次にFIELDWIDTHSgawksの\s/\S略語を使用します[[:space:]]/[^[:space:]]):

$ cat tst.awk
BEGIN { OFS="\t" }

/^\s*$/ { next }        # skip blank lines

/^\s*QSUM\s/ {          # start of a new record
    numRecs++
    lineNr = 0
}

{
    if ( (++lineNr) % 2 == 1 ) {
        # tags line so find every tag and field width
        FPAT = "\\S+\\s*"
        $0 = $0
        for (i=1; i<=NF; i++) {
            tag = $i
            fw = (i>1 ? fw " " : "") (i<NF ? length(tag) : "*")
            gsub(/^\s+|\s+$/,"",tag)
            if ( !(tag in tagNames2nrs) ) {
                tagNrs2names[++numTags] = tag
                tagNames2nrs[tag] = numTags
            }
            fldNr2tagNr[i] = tagNames2nrs[tag]
        }
        FPAT = ""
    }
    else {
        # vals line so use the field widths found for tags
        FIELDWIDTHS = fw
        $0 = $0
        for (i=1; i<=NF; i++) {
            val = $i
            gsub(/^\s+|\s+$/,"",val)
            tagNr = fldNr2tagNr[i]
            vals[numRecs,tagNr] = val
        }
        FIELDWIDTHS = ""
    }
}

END {
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tagNrs2names[tagNr]
        printf "%s%s", tag, (tagNr<numTags ? OFS : ORS)
    }

    for (recNr=1; recNr<=numRecs; recNr++) {
        for (tagNr=1; tagNr<=numTags; tagNr++) {
            val = vals[recNr,tagNr]
            printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file | column -s$'\t' -t
QSUM  HEADER                        STOCK  DATE    TIME       TI  JPS  TNN  LTNN  PP   JP  AA  NS            CPOODE  TYPE  AI  PNC   FLAG    CPO
206   CC-USER REJECT SENT           TNPPP  200322  104914600           8    6     0    1   4   899599991119          12    18
206   CC-USER REJECT SENT           TNPPP  200322  115844000           8    6     0    1   4   899599991555          12    18
103   SUITE FAIL, SUBTRACT FAILURE  TPNRM  200318  031124100  2        177        123  1   4   999999999999                    1499  ORIGIN
103   SUITE FAIL, SUBTRACT FAILURE  TPNRM  200318  031124200  2        177        123  1   4   999999999999                    1499  ORIGIN

各行ペアには異なるフィールドがあり、その一部は空であるため、データを読み取るには固定フィールドに依存する必要がありますが、読み取ろうとする前にフィールド数とフィールド幅を知ることはできません。したがって、このスクリプトはFPATを使用して、各タグ行内のすべてのタグ(名前、タイトル、タイトル)を検索します。

TI         JPS        TNN        LTNN       PP         JP

各フィールドの幅(タグ名と次のスペースを含む)を決定し、FIELDWIDTHSを使用して後続の値行から値を読み取ることができます。

                      8          6          0          1

固定幅のフィールドなので、フィールドが空の場合も同様です。

私はそれについて言及したり、一般的に説明しません。 IMHOコードは非常に明確で、テキスト操作に関する多くの質問をしていたので、いくつかのコードを読んでawkについて学ぶ時間です。マニュアルページを参照してくださいprint。変数がどの値を持っているかを確認する必要がある場所にステートメントなどを追加する必要があります。具体的な質問がある場合は、お気軽にお問い合わせください。

上記はあなたの質問と同じファイルであるこの入力ファイルに対して実行されましたが、QSUM、STOCK、DATA、およびTIMEヘッダーの一貫性のないソートが修正されました。あなたの実際の入力がそれほど混乱しているとは思わないからです。 up(しかし、そうであれば処理しやすいでしょう):

$ cat file

QSUM HEADER                          STOCK   DATE    TIME
206  CC-USER REJECT SENT             TNPPP   200322  104914600

TI         JPS        TNN        LTNN       PP         JP
                      8          6          0          1

AA         NS                                          CPOODE
4          899599991119

TYPE       AI
12         18

QSUM HEADER                          STOCK   DATE    TIME
206  CC-USER REJECT SENT             TNPPP   200322  115844000

TI         JPS        TNN        LTNN       PP         JP
                      8          6          0          1

AA         NS                                          CPOODE
4          899599991555

TYPE       AI
12         18
QSUM HEADER                         STOCK   DATE    TIME
103  SUITE FAIL, SUBTRACT FAILURE   TPNRM   200318  031124100

TI         PNC        TNN        PP         JP         AA
2          1499       177        123        1          4

NS                                          FLAG
999999999999                                ORIGIN

TI         CPO


QSUM HEADER                         STOCK   DATE    TIME
103  SUITE FAIL, SUBTRACT FAILURE   TPNRM   200318  031124200

TI         PNC        TNN        PP         JP         AA
2          1499       177        123        1          4

NS                                          FLAG
999999999999                                ORIGIN

TI         CPO

おすすめ記事