【问题标题】:How to replace a string in a file, when that string is a bash command [duplicate]当该字符串是bash命令时,如何替换文件中的字符串[重复]
【发布时间】:2020-09-02 01:15:27
【问题描述】:

我需要搜索文件中的一个字符串并将其替换为另一个字符串。通常可以使用

sed -i 's/old-text/new-text/g' input.txt

但是,如果替换字符串是诸如

之类的命令的选项,这将不起作用
INCPATH = -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I.

我将这些字符串存储在 bash 变量中

new_string=$(sed -n '/INCPATH       = /,/^$/p' Makefile_qmake)
old_string=$(sed -n '/INCPATH       = /,/^$/p' Makefile_skeleton)

我需要执行替换,将文件中的旧字符串替换为新字符串。

sed -i "s/'${old_string}'/'${new_string}'/" Makefile

问题是sed 认为替换字符串包含自己的命令。我不希望替换字符串中的命令被解释为命令。我希望它执行盲搜索和替换,而不扩展命令。

【问题讨论】:

  • sed 可能不是最好的工具。 perl 有一个引号运算符,它会自动转义正则表达式中所有具有特殊含义的字符。
  • @Barmar 举个例子?
  • 您能否提供old_stringnew_string 的示例以及预期输出?
  • @ThatsWhatSheCoded old_stringnew_string 都是 Makefile 的一部分,无论是选项还是规则。

标签: bash sed replace


【解决方案1】:

如果您的模式字符串或替换字符串包含“/”字符,我建议更改 sed 分隔符:

old_string=${old_string//[[:space:]]/ }
new_string=${new_string//[[:space:]]/ }
sed -i "s;'${old_string}';'${new_string}';" Makefile

【讨论】:

  • sed: -e expression #1, char 306: unterminated s' 命令`
  • @Galaxy 由于您在上面的另一条评论中澄清了任何一个字符串可能包含制表符和换行符,我已经更新了我的答案,首先将所有空格转换为单个空格,从而解决 unterminated 中的错误您的上述评论。
【解决方案2】:

在新旧字符串上都使用转义以避免与特殊元字符相关的问题:

old_string='your_string_to_find'
new_string='your_string_to_replace_with'

IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<< "${new_string}")
replaceEscaped=${REPLY%$'\n'}
searchEscaped=$(sed -e 's/[^^]/[&]/g; s/\^/\\^/g; $!a\'$'\n''\\n' <<<"${old_string}" | tr -d '\n')

sed -i "s/${searchEscaped}/${replaceEscaped}/g" file

请参考Is it possible to escape regex metacharacters reliably with sed

【讨论】:

    猜你喜欢
    • 2017-04-01
    • 2016-09-13
    • 2021-08-12
    • 1970-01-01
    • 2017-03-06
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    相关资源
    最近更新 更多