Unix 使用Awk如何在文件之间合并字段,文件1的F2加上文件2中F2的最后8char

Unix 使用Awk如何在文件之间合并字段,文件1的F2加上文件2中F2的最后8char,unix,awk,sed,Unix,Awk,Sed,我有两个文件file1和file2,我需要通过合并file1的F2加上file2中F2的最后8char来替换file1的F1值 文件1: 123456|AAAAAAA|BBBBBB|CCCCCCC 444444|kkkkkkk|rrrrrr|NNNNNNN 文件2: AAAAAAA|DDDDDD12345678 kkkkkkk|987654321aaaaa 预期产量 123456|AAAAAAA12345678|BBBBBB|CCCCCCC 444444|kkkkkkk321aaaaa|rr

我有两个文件file1和file2,我需要通过合并file1的F2加上file2中F2的最后8char来替换file1的F1值

文件1:

123456|AAAAAAA|BBBBBB|CCCCCCC
444444|kkkkkkk|rrrrrr|NNNNNNN
文件2:

AAAAAAA|DDDDDD12345678
kkkkkkk|987654321aaaaa
预期产量

123456|AAAAAAA12345678|BBBBBB|CCCCCCC
444444|kkkkkkk321aaaaa|rrrrrr|NNNNNNN
我试过使用Bellow awk函数,但不确定如何从文件2中获取F2的最后8个字符

# awk -F"|" 'NR==FNR{a[$1]=$2} NR>FNR{$2=$2a[$2];print}' OFS='|' File2 File1      
123456|AAAAAAADDDDDD12345678|BBBBBB|CCCCCCC
444444|kkkkkkk987654321aaaaa|rrrrrr|NNNNNNN

要获取
a[$2]
的最后8个字符,需要使用
substr

substr(a[$2],length(a[$2])-7)
上面的子字符串为
a[$2]
,从位置
length(a[$2])-7开始

通过这一更改,您的代码将生成所需的输出:

$ awk -F"|" 'NR==FNR{a[$1]=$2} NR>FNR{$2=$2 substr(a[$2],length(a[$2])-7);print}' OFS='|' File2 File1 
123456|AAAAAAA12345678|BBBBBB|CCCCCCC
444444|kkkkkkk321aaaaa|rrrrrr|NNNNNNN
正如Ghoti在评论中指出的那样,更常见的awk样式是使用
next
,以避免需要第二个条件
NR>FNR
,如下所示:

awk -F"|" 'NR==FNR{a[$1]=$2;next} {$2=$2 substr(a[$2],length(a[$2])-7);print}' OFS='|' File2 File1
awk
遇到
next
时,它跳过其余命令并在
next
行重新开始

由于
awk
程序员通常看重简洁而不是清晰,因此通常会看到
print
语句被
1
替换:

awk -F"|" 'NR==FNR{a[$1]=$2;next} {$2=$2 substr(a[$2],length(a[$2])-7)} 1' OFS='|' File2 File1

在这种情况下,
1
是一个条件,它的计算结果始终为true。由于没有任何命令与该条件相关联,因此会执行默认命令,即
print

尝试将其格式设置得更好一点-我认为这不一定是一个坏问题,但像这样它可能不会得到答案。请注意
substr(a[$2],length(a[$2])-7即可;如果不包括长度,它将一直延伸到字符串的末尾,在本例中这是一个可预测的距离。@ghoti非常好。这是一个很好的简化。答案已更新。另一个简化可能是避免第二个条件:
'NR==FNR{a[$1]=substr($2,length($2)-7);next}{$2=$2a[$2]}.1'
next
使事情本地化,还允许您使用
1
速记。