我正在尝试使用awk& amp进行一些大规模的字符串替换。 gsub,从文件(字典)中读取模式及其等价物,并在第二个(input.txt)中替换它们。
dictionary.txt:
c SUB1
u SUB2
我想将每一行存储在一个数组中,并搜索第二个文件中的第一个字段(c
或u
),将其更改为SUB1
或SUB2
。我想改变整个字段,而不仅仅是字符串出现。
我要修改的文件是input.txt
:
a ca mor
c cq nye
e c ult
d u cult
u as agc
x ul og
为了使事情变得更复杂,我只想在file1
的第一列和第二列中应用替换(但是仍打印第三列)。
到目前为止,我已经得到了这个:
awk 'NR==FNR{a[$1]=$2;next} {for (i in a) { gsub(i,a[i],$1)};{ gsub(i,a[i],$2)} }1' dictionary.txt input.txt
在第一个块中,我将dictionary.txt
中的行存储在数组a
中,使用1作为键,使用2作为值(而NR == FNR,而我正在读取第一个文件)。
然后,对于数组中的每个键,我使用gsub(字段$ 1和$ 2)在input.txt
上执行2次替换。
这是当前的输出:
a SUB1a mor
SUB1 SUB1q nye
e SUB1 ult
d u cult
SUB2 as agc
x ul og
正如您所看到的,我现在将c
的所有实例替换为SUB1
,即使它们是该字段的一部分(请注意第一行,第二个字段。我想避免此
此外,出于某种原因,第二个替换(u
到SUB2
)在第一个字段中工作(参见第5行,第1个字段),但不在第二个字段中工作(参见第4行和最后一行) ,第2场)。
这是我需要的输出:
a ca mor
SUB1 cq nye
e SUB1 ult
d SUB2 cult
SUB2 as agc
x ul og
你对我遗失的内容有什么看法吗?
请注意,我正在尝试避免基于sed的答案,因为我的真实数据涉及两个文件中的大量行,并且需要太长时间。非常感谢。
最佳,
答案 0 :(得分:2)
当你在寻找整个领域的精确字符串匹配时,我建议你这样做:
awk 'NR == FNR { a[$1] = $2; next }
$1 in a { $1 = a[$1] } $2 in a { $2 = a[$2] } 1' dictionary.txt input.txt
这不是使用正则表达式,而是简单地进行字符串比较,并在完全匹配的情况下进行替换。
感谢dave_thompson_085提出的建议。
答案 1 :(得分:1)
对于全字匹配问题,您可以使用^
和$
锚定正则表达式。
第二个问题似乎只是上面评论中解决的额外问题。
$ awk 'NR==FNR{a[$1]=$2;next} {for (i in a) {re="^"i"$"; sub(re,a[i],$1); sub(re,a[i],$2)}}1' dictionary.txt input.txt
a ca mor
SUB1 cq nye
e SUB1 ult
d SUB2 cult
SUB2 as agc
x ul og