GNU 模式匹配并替换准确数量的字符

Ish*_*han 2 linux sed gnu regular-expression wildcards

这个问题可能已被列出,但我无法找到一个确切的命中。

我试图浏览一个文件,匹配一个模式并用其他东西替换它。但是,还有其他模式出现,但我只需要替换那些长度为 17 个字符的模式。

例子:

内容:

dlkfhfd|fedfe|dfwe3f347fde|3745978|dlkfhr**|376663781736102|**fedfe|dfwe3f347fde
Run Code Online (Sandbox Code Playgroud)

期待:

dlkfhfd|fedfe|dfwe3f347fde|3745978|dlkfhr**|37xxxxxxxxxxxxx|**fedfe|dfwe3f347fde
Run Code Online (Sandbox Code Playgroud)

进展:我能够将表达式与正则表达式模式匹配: **\|37[0-9]{13}\|**

但是,如果我将它放在 . 中sed,它只会替换文件中的所有内容。

sed -e s/\|37[0-9]{13}\|/\|37xxxxxxxxxxxxx\|/g
Run Code Online (Sandbox Code Playgroud)

我的 sed 版本是 4.2.2

Kus*_*nda 5

您的正则表达式是基本正则表达式和扩展正则表达式的混合体。

作为扩展的正则表达式(使用{13}\|作为文字管道):

sed -E 's/\|37[0-9]{13}\|/|37xxxxxxxxxxxxx|/g'
Run Code Online (Sandbox Code Playgroud)

或者,作为基本的正则表达式(使用\{13\}|作为文字管道):

sed 's/|37[0-9]\{13\}|/|37xxxxxxxxxxxxx|/g'
Run Code Online (Sandbox Code Playgroud)

这会将您的示例字符串变成

dlkfhfd|fedfe|dfwe3f347fde|3745978|dlkfhr**|37xxxxxxxxxxxxx|**fedfe|dfwe3f347fde
Run Code Online (Sandbox Code Playgroud)

另请注意,无需|在表达式的替换部分中转义 ,因为该部分永远不会被解释为正则表达式。


awk

awk -F '|' -vOFS='|' '
    {
        for (i=1; i<=NF; ++i))
            if (length($i)==15 && match($i,"^37[0-9]"))
                $i="37xxxxxxxxxxxxx"
        print 
     }'
Run Code Online (Sandbox Code Playgroud)

可以在gsub()这里使用,但这会使它或多或少与sed解决方案相同,因此很无聊。

这样做的好处是,即使该字段|在两端都没有被分隔,替换也会发生在第一个或最后一个字段中。