AWK - 使用多个文件查找和替换多个字段
Posted
技术标签:
【中文标题】AWK - 使用多个文件查找和替换多个字段【英文标题】:AWK - lookup and replace multiple fields using multiple files 【发布时间】:2014-11-13 19:19:53 【问题描述】:无法确定我需要在 AWK 中实现什么。我有 2 个文件:
文件1
1|2|3|4|5|6|7|8|9|AAA|BBB|12|13|
1|2|3|4|5|6|7|8|9|CCC|DDD|12|13|
1|2|3|4|5|6|7|8|9|EEE|FFF|12|13|
1|2|3|4|5|6|7|8|9|GGG|HHH|12|13|
1|2|3|4|5|6|7|8|9|III|JJJ|12|13|
1|2|3|4|5|6|7|8|9|KKK|LLL|12|13|
1|2|3|4|5|6|7|8|9|MMM|NNN|12|13|
1|2|3|4|5|6|7|8|9|OOO|PPP|12|13|
1|2|3|4|5|6|7|8|9|QQQ|RRR|12|13|
1|2|3|4|5|6|7|8|9|SSS|TTT|12|13|
1|2|3|4|5|6|7|8|9|UUU|VVV|12|13|
1|2|3|4|5|6|7|8|9|WWW|XXX|12|13|
1|2|3|4|5|6|7|8|9|YYY|ZZZ|12|13|
1|2|3|4|5|6|7|8|9|QWE|RTY|12|13|
1|2|3|4|5|6|7|8|9|ASD|FGH|12|13|
1|2|3|4|5|6|7|8|9|ZXC|VBN|12|13|
1|2|3|4|5|6|7|8|9|ASS|BOB|12|13|
1|2|3|4|5|6|7|8|9|FFR|ERD|12|13|
文件2
AAA|BBB|AA1|BB1|
CCC|DDD|CC1|DD1|
EEE|FFF|EE1|FF1|
GGG|HHH|GG1|HH1|
III|JJJ|II1|JJ1|
KKK|LLL|KK1|LL1|
MMM|NNN|MM1|NN1|
OOO|PPP|OO1|PP1|
QQQ|RRR|QQ1|RR1|
SSS|TTT|SS1|TT1|
我需要将文件 1 中的字段 10 和 11 替换为文件 2 中的字段 3 和 4,其中文件 1 中的字段 10 和 11 等于文件 2 中的字段 1 和 2。
所以我希望这个例子的输出是:
1|2|3|4|5|6|7|8|9|AA1|BB1|12|13|
1|2|3|4|5|6|7|8|9|CC1|DD1|12|13|
1|2|3|4|5|6|7|8|9|EE1|FF1|12|13|
1|2|3|4|5|6|7|8|9|GG1|HH1|12|13|
1|2|3|4|5|6|7|8|9|II1|JJ1|12|13|
1|2|3|4|5|6|7|8|9|KK1|LL1|12|13|
1|2|3|4|5|6|7|8|9|MM1|NN1|12|13|
1|2|3|4|5|6|7|8|9|OO1|PP1|12|13|
1|2|3|4|5|6|7|8|9|QQ1|RR1|12|13|
1|2|3|4|5|6|7|8|9|SS1|TT1|12|13|
1|2|3|4|5|6|7|8|9|UUU|VVV|12|13|
1|2|3|4|5|6|7|8|9|WWW|XXX|12|13|
1|2|3|4|5|6|7|8|9|YYY|ZZZ|12|13|
1|2|3|4|5|6|7|8|9|QWE|RTY|12|13|
1|2|3|4|5|6|7|8|9|ASD|FGH|12|13|
1|2|3|4|5|6|7|8|9|ZXC|VBN|12|13|
1|2|3|4|5|6|7|8|9|ASS|BOB|12|13|
1|2|3|4|5|6|7|8|9|FFR|ERD|12|13|
非常感谢您的帮助。
【问题讨论】:
你的真实文件长度也固定吗?还是只是为了想法和字段可能有可变长度? 嗨,真实文件没有不同的字段长度。 unix.stackexchange.com/questions/106645/… 我认为可以帮助你。我现在不能写答案 【参考方案1】:这样可以吗?
awk 'BEGINFS=OFS="|"
FNR==NR a[$1,$2]=$3; b[$1,$2]=$4; next
($10,$11) in a f10=a[$10,$11];$11=b[$10,$11];$10=f10
1' f2 f1
测试
$ awk 'BEGINFS=OFS="|" FNR==NR a[$1,$2]=$3; b[$1,$2]=$4; next ($10,$11) in a f10=a[$10,$11];$11=b[$10,$11];$10=f101' f2 f1
1|2|3|4|5|6|7|8|9|AA1|BB1|12|13|
1|2|3|4|5|6|7|8|9|CC1|DD1|12|13|
1|2|3|4|5|6|7|8|9|EE1|FF1|12|13|
1|2|3|4|5|6|7|8|9|GG1|HH1|12|13|
1|2|3|4|5|6|7|8|9|II1|JJ1|12|13|
1|2|3|4|5|6|7|8|9|KK1|LL1|12|13|
1|2|3|4|5|6|7|8|9|MM1|NN1|12|13|
1|2|3|4|5|6|7|8|9|OO1|PP1|12|13|
1|2|3|4|5|6|7|8|9|QQ1|RR1|12|13|
1|2|3|4|5|6|7|8|9|SS1|TT1|12|13|
1|2|3|4|5|6|7|8|9|UUU|VVV|12|13|
1|2|3|4|5|6|7|8|9|WWW|XXX|12|13|
1|2|3|4|5|6|7|8|9|YYY|ZZZ|12|13|
1|2|3|4|5|6|7|8|9|QWE|RTY|12|13|
1|2|3|4|5|6|7|8|9|ASD|FGH|12|13|
1|2|3|4|5|6|7|8|9|ZXC|VBN|12|13|
1|2|3|4|5|6|7|8|9|ASS|BOB|12|13|
1|2|3|4|5|6|7|8|9|FFR|ERD|12|13|
说明
BEGINFS=OFS="|"
将输入和输出字段分隔符设置为|
。
FNR==NR a[$1,$2]=$3; b[$1,$2]=$4; next
在读取给定的第一个文件 (f2
) 时,将第三个字段存储在数组 a[]
中,将第四个字段存储在数组 b[]
中,索引由 ($1,$2)
对给出。
($10,$11) in a f10=a[$10,$11];$11=b[$10,$11];$10=f10
在遍历给定的第二个文件 (f1
) 时,检查 ($10,$11)
对是否存储在数组 a[]
中。如果是这样,请进行更换。否则,线条将保持原样。
1
根据 True 条件,打印当前行。
【讨论】:
也可以使用awk 'BEGINFS=OFS="|" FNR==NR a[$1 FS $2]=$3 FS $4; next ($10 FS $11) in a $10=a[$10 FS $11];$11=""1' f2 f1
之类的东西,通过$1 FS $2
索引存储所有内容。无论如何,这会导致额外的|
。以上是关于AWK - 使用多个文件查找和替换多个字段的主要内容,如果未能解决你的问题,请参考以下文章