在AWK中以不同的方式替换多次出现的相同字符

时间:2015-02-25 15:38:38

标签: regex replace awk substitution

我希望使用AWK替换csv文件中的多个字符,具体取决于它们周围的字符。

例如,在这一行:

“示例一;示例一;示例一; E.示例一”

我想用“EE”替换所有大写字母“E”,如果它们只在一个单词中使用大写字母,而用“Ee”代替单词大小写字母或缩写(就像E.,它是一个地址文件,所以没有这种情况也可能是一个句子的结尾)所以它应该是这样的:

“Eexample One;示例一; EEXAMPLEE ONEE; Ee.EEXAMPLEE One”

现在我试过的是:

{if ($0 ~/E[A-Z]+/)
    $0 = gensub(/E/,"EE","g",$0)
else if ($0 ~/[A-Z]E/)
    $0 = gensub(/E/,"EE","g",$0)
else
    $0 = gensub(/E/,"Ee","g",$0)
}

这在大多数情况下都可以正常工作,但是对于包含几个“E”的行(或者说那个问题),我希望将其替换为“Ee”而将其作为“EE”替换为在“E. EXAMPLE One”中,它匹配“EXAMPLE”中的E,并用“EE”替换该行中的所有“E”。

有更好的方法吗?如果在gensub中,我可以以某种方式使用吗?

ps:希望这是有道理的,我刚开始学习编程的基础知识!

1 个答案:

答案 0 :(得分:1)

$ cat tst.awk
{
    head = ""
    tail = $0
    while ( match(tail,/[[:alpha:]]+\.?/) ) {
        tgt = substr(tail,RSTART,RLENGTH)
        add = (tgt ~ /^[[:upper:]]+$/ ? "E" : "e")
        gsub(/E/,"&"add,tgt)
        head = head substr(tail,1,RSTART-1) tgt
        tail = substr(tail,RSTART+RLENGTH)
    }
    print head tail
}

$ awk -f tst.awk file
Eexample One; example one; EEXAMPLEE ONEE; Ee. EEXAMPLEE One

目前尚不清楚如何区分一串字母后跟一段句子作为缩写或只是一句话的结尾。