【问题标题】:Bash script to replace this pattern in a file with anotherBash 脚本将文件中的此模式替换为另一个
【发布时间】:2019-11-21 08:05:26
【问题描述】:

我正在尝试创建一个 bash 脚本来替换所有出现的

<?= /* @noEscape */ __('any random string, of any length') ?>

<?= $block->escapeHtml(__('any random string, of any length')) ?>

在特定的文件或目录中。

问题是内部字符串可以是任何东西。

到目前为止,我已经尝试过使用sed。也许这不是最好的方法。

有什么想法吗?

#!/bin/bash
sed 's/\/\* @noEscape \*\/ __\('.*'\)/$block->escapeHtml\('.*'\)\)/g' $1 > $1.test
mv $1.test $1

【问题讨论】:

  • “随机字符串”是否包含单引号 (') 或右括号 ()) 或结束标记 (?>)?结束标签 (?>) 是否不会与开始标签出现在同一行?是否有任何行包含超过一组 <?= ... ?>(甚至是部分)?
  • @jhnc 好点。是的,有时会出现这种情况。在这种情况下,也许我应该手动进行,但最好是逐个文件地进行,然后我可以仔细检查。
  • 你需要一个可以检测匹配<?=/?>的工具。最好使用理解模板语言的工具而不是 sed。

标签: bash replace


【解决方案1】:

我不太确定,如果你真的想用.*替换内部字符串,我猜你想用原始字符串替换它,对吧?

那么你可以这样做:

#!/bin/bash
sed -e"s|/\* @noEscape \*/ __(\('.*'\))|\$block->escapeHtml(\1)|g" $1 > $1.test
mv $1.test $1

如果您真的想用 .* 替换内部字符串(例如,如果您打算生成正则表达式):

#!/bin/bash
sed -e"s|/\* @noEscape \*/ __(\('.*'\))|\$block->escapeHtml('.*')|g" $1 > $1.test
mv $1.test $1

在两个版本中,我都使用了's|...' s 信号sed 后面的第二个字符,我想使用什么分隔符。我选择了|,所以不需要转义/。 如果您想将$block 替换为shell 变量block 的内容,您只需删除上面$block 之前的\

sed 中的( 正则表达式(没有转义)表示字符(,而\( 是捕获组的开始,以\) 结尾,因此(\('.*'\)) 捕获被包围的字符串('') 并将其放入捕获组。因为它是正则表达式中的第一个捕获组,所以您可以通过 \1 在替换字符串中获取其内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-19
    • 2011-08-28
    • 2012-08-25
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    相关资源
    最近更新 更多