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