我必须合并两个文件并从第二个文件中删除标头。输出应该有新的序列号
前文件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
如果可能的话,如何更改 seq 编号并在同一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
如果您想以与现有输入相同宽度的 0 填充字符串打印新序列号,则使用 GNU awk 将第三个参数设置为 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
以及任何 awk:
$ 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