将正则表达式中的所有字符替换为另一个字符?

时间:2018-11-01 22:27:05

标签: regex sed posix

我正在对文件进行分析,我想屏蔽某些字符(同时保留其原始字节数),然后再将该文件移到管道中。例如,给定file.txt

Hello there Cory Klein
Have fun
Hello there Samantha Rodgers

编写正则表达式以匹配名称,并使用XXXXX替换它们,使用sed非常简单:

$ 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

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

任何常规的POSIX工具都可以使用sedawkperl等。我敢肯定我可以编写一个简单的python脚本来完成此任务,但是我很好奇是否仅使用正则表达式是可能的,这可能会更简洁。如果是这样,我很想学习如何在将来将其应用到其他地方。

2 个答案:

答案 0 :(得分:2)

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

/Hello there/{...}

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

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

我们将使用Hello there保留\1及其前面的字符。

整个命令将是:

$ sed -r '/Hello there/{s/(^.*Hello there *)?[^[:space:]]/\1x/g}' file
Hello there xxxx xxxxx
Have fun
Hello there xxxxxxxx xxxxxxx

答案 1 :(得分:1)

Perl支持其正则表达式集的高级功能,因此使用Perl可以使其更短:

perl -pe 's/(Hello there|\G(?!\A)) *\K\S/x/g' file

请参见live demo here

RegExp故障:

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

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