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 - 使用多个文件查找和替换多个字段的主要内容,如果未能解决你的问题,请参考以下文章

在多个文件中查找和替换正则表达式的最佳工具是啥?

使用 .bat 文件在目录中包含的多个文件中查找和替换字符串

在多个文件中进行查找/替换的最佳方法?

在多个批处理文件中查找和替换

Perl:在多个文本文件中查找和替换特定字符串

MS Access 在多个表的列字段中查找和替换文本