使用另一个字符替换正则表达式匹配中的所有字符?

3

我正在对一个文件进行分析,希望在将此文件传递下一个流程之前,对其中的一些字符进行掩码处理(同时保留它们原始的字节计数)。例如,给定file.txt

Hello there Cory Klein
Have fun
Hello there Samantha Rodgers

使用sed编写正则表达式来匹配名称并将其替换为XXXXX非常简单:
$ sed -e "s/\(Hello there \).*/\1XXXXX/" file.txt
Hello there XXXXX
Have fun
Hello there XXXXX

但是我想用X字符替换名称中的每个字符,就像这样:

Hello there XXXX XXXXX
Have fun
Hello there XXXXXXXX XXXXXXX

如何用另一个字符替换与正则表达式匹配的所有字符?

使用任何正则表达式工具,例如sedawkperl等。我确定我可以编写一个简单的Python脚本来完成这个任务,但我很好奇是否可以仅使用正则表达式实现,这可能更为简洁。如果是这样,我很想学习如何做到这一点,以便将来在其他地方可以应用该概念。


2
使用Perl很容易,perl -lpe 's/Hello there\s*\K(.*)/$1=~s#\S#X#gr/ge'演示)。 - Wiktor Stribiżew
在这种情况下,您如何定义名称?在正则表达式中,您需要指定每个名称以匹配或跳过每个模式。不清楚您是否打算这样做。 - dawg
2个回答

2

使用sed命令,您需要使用地址来过滤掉不包含Hello there的行:

/Hello there/{...}

然后将位于Hello there之后的任何单个非空白字符替换为一个x

s/(^.*Hello there *)?[^[:space:]]/\1x/g

我们使用\1来保留Hello there及其前面的字符。
整个命令如下:
$ sed -r '/Hello there/{s/(^.*Hello there *)?[^[:space:]]/\1x/g}' file
Hello there xxxx xxxxx
Have fun
Hello there xxxxxxxx xxxxxxx

1
GNU sed不仅如此,而且是一个很好的解决方案! - dawg
1
@oguzismail 你不应该改变正则表达式。相反,使用 sed '/Hello there/s/\(^.*Hello there *\)*[^[:space:]]/\1X/g' - revo

1
Perl支持一系列高级正则表达式特性,因此使用Perl可以更简短地实现此功能:
perl -pe 's/(Hello there|\G(?!\A)) *\K\S/x/g' file

请在此处查看演示

RegExp分解:

  • ( 开始分组
    • Hello there 匹配 Hello there
    • | 或者
    • \G(?!\A) 从上一个匹配结束的地方开始匹配
  • ) 结束分组
  • [ ]* 匹配任意空格
  • \K 忘记到目前为止匹配的内容
  • \S 匹配单个非空白字符

这将继续匹配在Hello there之后出现的所有非空白字符,并使用g标志将它们替换为x


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接