0

我有一个字典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] 移动到一个字符串中(然后可以解析转义字符),脚本将只替换字典中的第二条记录。为什么?以及如何解决?

这是脚本的当前第二部分:

{
for (key in rep)
orig=key
trans=rep[key]
gsub(/[\]\[^$.*?+{}\\()|]/, "\\\\&", orig)
gsub(orig,trans)
print
}

所有脚本都由awk -f translate.awk dict input

提前致谢!

4

2 回答 2

1

您的基本问题是在您不想要它们时在正则表达式和反向引用上下文中使用字符串,然后尝试转义字符串中的元字符以禁用您通过在这些上下文中使用它们启用的字符。如果您想要字符串,请在字符串上下文中使用它们,仅此而已。

你不会想要这个:

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
于 2016-11-11T22:12:04.150 回答
0

没关系问....只是缺少一些括号...?!

{
for (key in rep)
{
orig=key
trans=rep[key]
gsub(/[\]\[^$.*?+{}\\()|]/, "\\\\&", orig)
gsub(orig,trans)
}
print
}

奇迹般有效。

于 2016-11-11T20:51:04.850 回答