使用 awk 命令合并 2 个具有更新序列号的文件

使用 awk 命令合并 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

如果可能的话,如何更改 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

相关内容