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

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

这个问题可能已列出,但我无法找到准确的答案。

我正在尝试浏览一个文件,匹配一个模式并将其替换为其他内容。然而,该模式还出现在其他地方,但我只需要替换那些长度为 17 个字符的模式。

例子:

内容:

dlkfhfd|fedfe|dfwe3f347fde|3745978|dlkfhr**|376663781736102|**fedfe|dfwe3f347fde

期待:

dlkfhfd|fedfe|dfwe3f347fde|3745978|dlkfhr**|37xxxxxxxxxxxxx|**fedfe|dfwe3f347fde

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

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

sed -e s/\|37[0-9]{13}\|/\|37xxxxxxxxxxxxx\|/g

我的sed版本是4.2.2

答案1

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

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

sed -E 's/\|37[0-9]{13}\|/|37xxxxxxxxxxxxx|/g'

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

sed 's/|37[0-9]\{13\}|/|37xxxxxxxxxxxxx|/g'

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

dlkfhfd|fedfe|dfwe3f347fde|3745978|dlkfhr**|37xxxxxxxxxxxxx|**fedfe|dfwe3f347fde

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


awk

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

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

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

相关内容