我有一个字典dict
,其中记录以“:”分隔,数据字段按新行分隔,例如:
:one
1
:two
2
:three
3
:four
4
现在我希望awk替换input
中每条记录的所有匹配项
文件,例如
onetwotwotwoone
two
threetwoone
four
我的第一个awk脚本看起来像这样,工作得很好:
BEGIN { RS = ":" ; FS = "\n"}
NR == FNR {
rep[$1] = $2
next
}
{
for (key in rep)
grub(key,rep[key])
print
}
给我:
12221
2
321
4
不幸的是,另一个dict文件包含正则表达式使用的一些字符,因此我必须在脚本中替换转义字符。通过将key和rep [key]移动到一个字符串(然后可以解析为转义字符),脚本将只替换dict中的第二个记录。为什么?以及如何解决?
这是脚本当前的第二部分:
{
for (key in rep)
orig=key
trans=rep[key]
gsub(/[\]\[^$.*?+{}\\()|]/, "\\\\&", orig)
gsub(orig,trans)
print
}
所有脚本均由awk -f translate.awk dict input
提前致谢!
答案 0 :(得分:1)
您的基本问题是在不需要它们时使用regexp和backreference上下文中的字符串,然后尝试转义字符串中的元字符以通过在这些上下文中使用它们来禁用您启用的字符。如果你想要字符串,请在字符串上下文中使用它们,这就是全部。
你不会想要这个:
gsub(regexp,backreference-enabled-string)
你想要更像这样的东西:
index(...,string) substr(string)
我认为这就是你要做的事情:
$ cat tst.awk
BEGIN { FS = ":" }
NR == FNR {
if ( NR%2 ) {
key = $2
}
else {
rep[key] = $0
}
next
}
{
for ( key in rep ) {
head = ""
tail = $0
while ( start = index(tail,key) ) {
head = head substr(tail,1,start-1) rep[key]
tail = substr(tail,start+length(key))
}
$0 = head tail
}
print
}
$ awk -f tst.awk dict file
12221
2
321
4
答案 1 :(得分:0)
没关系...... 只是缺少一些括号......?!
{
for (key in rep)
{
orig=key
trans=rep[key]
gsub(/[\]\[^$.*?+{}\\()|]/, "\\\\&", orig)
gsub(orig,trans)
}
print
}
就像一个魅力。