【问题标题】:Sed find/inline replace, escaping some charactersSed 查找/内联替换,转义一些字符
【发布时间】:2016-09-05 19:13:57
【问题描述】:

我有一堆需要替换的数据库连接设置,希望这里有人可以用 sed 为我指明正确的方向。通常我使用 find 和 sed 组合来执行此操作,如下所示:

sudo find . -name "*.php" -print0 |
sudo xargs -0 sed -i '' -e 's#:/usr/share/php/pear:#:/usr/lib/php5/pear/:/usr/share/php/pear:#g'

但是对于数据库连接字符串,我需要替换如下所示的行:

define('DBUSER', 'dbuser');

由于各种原因,我不能只对用户名本身进行 sed,因此我需要更严格地定义可替换文本。不幸的是,我在正则表达式方面的有限技能使我无法正确地逃避整个序列,以便可以被 sed 找到并正确替换。我需要做什么才能基本上使用我通常用来替换那些 DBUSER 字符串中的用户名的相同 find/sed 命令?我尝试对单引号进行反斜杠转义,以及对每个单引号进行双引号,但这些都不起作用。这是在最新的 Ubuntu 14.04 系统上,没有任何花哨的定制。

提前感谢你们提供的任何帮助。我真的很感激。

【问题讨论】:

  • 你可能只需要加倍 \ 转义它们。一个\用于bash,另一个用于sed
  • @CarlTashian 不,无论您使用什么工具(sed、awk 等),无论使用多少次,都不能在单引号分隔的 shell 脚本中使用单引号你试图逃避它。
  • 感谢@EdMorton,这很有道理。
  • @CarlTashian 不客气。不,永远不要双引号脚本,除非它是绝对必要的,并且你有一个与双引号脚本产生的行为相关的非常具体的目的(即你试图让某事发生,而不是试图阻止某事发生,并且加倍引用是这样做的方法)并完全理解警告/哥特式。请参阅my answer 了解原因。

标签: regex linux bash sed find


【解决方案1】:

您可能需要三个反斜杠来表示正则表达式中的单引号字符。原因如下:

~$ echo 'sdfsdf'
sdfsdf
~$ echo \'sdfsdf\'
'sdfsdf'
~$ echo \\'sdfsdf\\'
\sdfsdf\\
~$ echo \\\'sdfsdf\\\'
\'sdfsdf\'

编辑:实际上这不适用于sed。但是如果你在正则表达式周围使用双引号,你应该只需要一个反斜杠:

~$ sed -e "s#\'hi\'#abc#g"
'hi'
abc

【讨论】:

    【解决方案2】:

    无论您使用什么工具(sed、awk 等),无论您尝试转义多少次,shell 都不允许您在单引号分隔的 shell 脚本中使用单引号它。

    使用 sed 执行此操作的常用方法是在 sed 命令行中添加单引号以暂时跳出 sed 并进入 shell:

    sed 'in sed'back in shell'in sed'
    

    在那里转义单引号

    sed 'in sed'\''in sed'
    

    具体来说:

    $ echo "foo define('DBUSER', 'dbuser'); bar" |
        sed 's/define('\''DBUSER'\'', '\''dbuser'\'');/you win $100/'
    foo you win $100 bar
    
    $ echo "foo define('DBUSER', 'dbuser'); bar" |
        sed 's/define('\''DBUSER'\'', '\''dbuser'\'');/voila!/'
    foo voila! bar
    

    永远不要用双引号而不是单引号括起 sed 脚本或任何其他脚本(解决此问题的另一种经常被建议的方法),因为尽管这 似乎很简单,就像大多数看起来很简单的事情一样shell 编程,它非常脆弱,你必须留意并处理变量扩展和其他问题,例如:

    $ echo "foo define('DBUSER', 'dbuser'); bar" |
        sed "s/define('DBUSER', 'dbuser');/you win $100/"
    foo you win 00 bar
    
    $ echo "foo define('DBUSER', 'dbuser'); bar" |
        sed "s/define('DBUSER', 'dbuser');/voila!/"
    -bash: !/: event not found
    

    【讨论】:

    • 太棒了,感谢详尽的解释和示例!
    猜你喜欢
    • 2015-01-17
    • 2013-03-23
    • 2012-02-14
    • 2012-02-17
    • 2019-11-15
    • 1970-01-01
    相关资源
    最近更新 更多