awkコマンドを使用して、更新されたシリアル番号に2つのファイルをマージします。

awkコマンドを使用して、更新されたシリアル番号に2つのファイルをマージします。

2つのファイルをマージし、2番目のファイルからヘッダーを削除する必要があります。出力には新しいシーケンス番号が必要です。

古いファイル 1.txt

H20200428  
DSEQ0000001USA  
DSEQ0000002MEXICO  
DSEQ0000003BRAZIL  
T00003

ファイル2.txt

H20200428  
DSEQ0000001USA  
DSEQ0000002MEXICO  
DSEQ0000003BRAZIL  
T00003

出力ファイルは次のようにする必要があります

H20200428  
DSEQ0000001USA  
DSEQ0000002MEXICO  
DSEQ0000003BRAZIL  
DSEQ0000004USA  
DSEQ0000005MEXICO  
DSEQ0000006BRAZIL  
T00006

awkファイルをマージしてヘッダーを削除しました。

awk 'FNR!=NR && FNR==1 {next} 1' file1.txt file2.txt > output.txt

可能であれば、どのようにシーケンス番号を変更し、awk同じコマンドにトレーラーレコードとD型レコード全体を含めることができますか?

事前にありがとう

答え1

次のことを試すことができます。

awk 'FNR==1 {if (NR>1) next; print;} \
     /^D/ {seq++; sid=sprintf("SEQ%07d",seq); sub(/SEQ[0-9]+/,sid); print} \
     END {printf("T%05d\n",seq);}' file1.txt file2.txt

これは

  • 最初の行が「現状のまま」印刷される最初のファイルを除く、すべてのファイルの最初の行をスキップします。
  • で始まるすべての行に対してDシーケンスカウンタをインクリメントし、seq既存のシーケンスを新しいシーケンスIDに置き換えて、ラインを印刷します。

ファイルの最後には、最後の値の合計が印刷されますseq

このソリューションは、2つ以上のファイルにも適用されます。

答え2

既存の入力と同じ幅のゼロパディング文字列で新しいシーケンス番号を印刷するには、GNU awkを使用して3番目の引数をmatch()に設定します。

$ cat tst.awk
NR==1 && FNR==1 { print }
FNR > 2 { printf "%s%0*d%s\n", prev[1], length(prev[2]), ++seqNr, prev[3] }
{ match($0,/([^1-9]+)([0-9]+)(.*)/,prev) }
END { printf "%s%0*d\n", prev[1], length(prev[2]), seqNr }

$ awk -f tst.awk file1 file2
H20200428
DSEQ0000001USA
DSEQ0000002MEXICO
DSEQ0000003BRAZIL
DSEQ0000004USA
DSEQ0000005MEXICO
DSEQ0000006BRAZIL
T00006

awkの場合(prev[]gawkスクリプトと比較するためにスカラーを使用する代わりに配列を保持する場合)は、次のようになります。

$ cat tst.awk
NR==1 && FNR==1 { print }
FNR > 2 { printf "%s%0*d%s\n", prev[1], lgth2, ++seqNr, prev[3] }
{
    match($0,/[^1-9]+/)
    prev[1] = substr($0,RSTART,RLENGTH)
    match($0,/[^1-9]+[0-9]+/)
    lgth2 = RLENGTH - length(prev[1])
    prev[3] = substr($0,RSTART+RLENGTH)
}
END { printf "%s%0*d\n", prev[1], lgth2, seqNr }

$ awk -f tst.awk file1 file2
H20200428
DSEQ0000001USA
DSEQ0000002MEXICO
DSEQ0000003BRAZIL
DSEQ0000004USA
DSEQ0000005MEXICO
DSEQ0000006BRAZIL
T00006

または、同じ数の先行ゼロを維持するには、GNU awkを使用します。

$ cat tst.awk
NR==1 && FNR==1 { print }
FNR > 2 { print prev[1] (++seqNr) prev[2] }
{ match($0,/([^1-9]+)[0-9]+(.*)/,prev) }
END { print prev[1] seqNr }

$ awk -f tst.awk file1 file2
H20200428
DSEQ0000001USA
DSEQ0000002MEXICO
DSEQ0000003BRAZIL
DSEQ0000004USA
DSEQ0000005MEXICO
DSEQ0000006BRAZIL
T00006

そしていくつかの奇妙な:

$ cat tst.awk
NR==1 && FNR==1 { print }
FNR > 2 { print prev[1] (++seqNr) prev[2] }
{
    match($0,/[^1-9]+/)
    prev[1] = substr($0,RSTART,RLENGTH)
    sub(/[^0-9]+[0-9]+/,"")
    prev[2] = $0
}
END { print prev[1] seqNr }

$ awk -f tst.awk file1 file2
H20200428
DSEQ0000001USA
DSEQ0000002MEXICO
DSEQ0000003BRAZIL
DSEQ0000004USA
DSEQ0000005MEXICO
DSEQ0000006BRAZIL
T00006

関連情報