使用给定文本

时间:2017-12-05 06:23:57

标签: regex linux replace

对于给定的路径,我希望使用标准的Linux shell命令将给定的正则表达式包装在该路径中的所有文件中或该路径的子目录中,并使用一些给定的文本。

更具体地说,使用诸如syslog(LOG_INFO,json_encode($obj));之类的断言命令将所有syslog命令包装成assert(syslog(LOG_INFO,json_encode($obj)));

我认为以下内容可能有效,但收到sed: -e expression #1, char 47: Invalid preceding regular expression错误。

sed -i -E "s/(?<=syslog\()(.*)(?=\);)/assert(syslog(\1));/" /path/to/somewhere

回应信息回应WiktorStribiżew的回答

我之前从未使用过sed。请确认我对你答案的理解:

sed -i "s/syslog(\(.*\));/assert(syslog(\1));/g" /path/to/somewhere
  • -i编辑文件。人们可以先在屏幕上看到将要更改的内容。
  • s替换文字
  • 模式和替换周围的三个/(即/pattern/replacement/)是分隔符,可以是任何单个字符,而不仅仅是/
  • syslog(\(.*\));带有一个占位符的模式。使用转义括号。
  • assert(syslog(\1));使用转义1(或23等)代替替换子字符串。
  • g替换所有而不仅仅是第一场比赛。

sed -i "s/syslog(.*);/assert(&);/g" /path/to/somewhere也能正常工作吗?

2 个答案:

答案 0 :(得分:1)

sed模式不支持(?<=...)(?=...)等外观。

您可以使用捕获组/替换反向引用:

sed -i "s/syslog(\(.*\));/assert(syslog(\1));/g" /path/to/somewhere

该模式具有BRE POSIX风格(未传递-E选项),因此要定义捕获组,您需要使用转义括号,未转义的括号将与字面括号匹配。

<强>详情

  • syslog( - syslog( substring
  • \(.*\) - 第1组:尽可能多的0个字符
  • ); - );子字符串

替换为assert(syslog(\1));,即匹配替换为assert(syslog(,组1的内容,然后));

答案 1 :(得分:0)

如果需要Perl兼容的正则表达式结构,可以使用Perl(原文如此)。

perl -i -pe 's/(?<=syslog\()(.*)(?=\);)/assert(syslog($1));/' /path/to/somewhere

无论这个特定的解决方案如何,我都假设您使用的是Unix-ish平台,我会切换到单引号。双引号内的反斜杠很麻烦(有时你需要加倍它们,有时候不需要)。

Perl在替换模式中优先于$1而不是\1,但后者在技术上也会起作用。