这个问题可能已列出,但我无法找到准确的答案。
我正在尝试浏览一个文件,匹配一个模式并将其替换为其他内容。然而,该模式还出现在其他地方,但我只需要替换那些长度为 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
,因此很无聊。
这样做的好处是,即使第一个或最后一个字段没有被|
两端分隔,替换也将发生在该字段中。