【发布时间】:2016-02-04 11:20:04
【问题描述】:
我正在尝试使用 awk 和 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 行,第一个字段)中有效,但在第二个字段中无效(参见第 4 行和最后一行,第 2 个字段) .
这是我需要的输出:
a ca mor
SUB1 cq nye
e SUB1 ult
d SUB2 cult
SUB2 as agc
x ul og
你对我缺少什么有什么想法吗?
请注意,我试图避免基于 sed 的答案,因为我的真实数据在两个文件中都涉及很多行,而且会花费很长时间。非常感谢。
最好的,
【问题讨论】:
-
在
for (i in a) { gsub(i,a[i],$1)};{ gsub(i,a[i],$2)}中,只有第一个gsub包含在for循环中。这是你的意图吗? -
不,这是一个错误。当我将其更改为
{for (i in a) { gsub(i,a[i],$1);gsub(i,a[i],$2)} }时,字典中第二行的问题就解决了。感谢您的关注。