sed替换单/双引文?

p4g*_*uru 14 text replace sed

sed替换一些单/双引号文本有一些困难,并且想知道这两个例子的正确方法是什么

从中更改Memached.ini文件内容

[server]
server[] = "localhost:11211"
Run Code Online (Sandbox Code Playgroud)

[server]
server[] = "localhost:11211"
server[] = "localhost:11212"
Run Code Online (Sandbox Code Playgroud)

并从中更改这些行的memcache.php文件内容

define('ADMIN_USERNAME','username');    // Admin Username
define('ADMIN_PASSWORD','password');    // Admin Password

$MEMCACHE_SERVERS[] = 'mymemcache-server1:11211'; // add more as an array
$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array
Run Code Online (Sandbox Code Playgroud)

define('ADMIN_USERNAME','myusername');  // Admin Username
define('ADMIN_PASSWORD','mypassword');      // Admin Password

$MEMCACHE_SERVERS[] = 'localhost:11211'; // add more as an array
$MEMCACHE_SERVERS[] = 'localhost:11212'; // add more as an array
Run Code Online (Sandbox Code Playgroud)

我试过这个例子

sed -i 's/'ADMIN_USERNAME','memcache'/'ADMIN_USERNAME','u'/g' /var/www/html/memcache.php
Run Code Online (Sandbox Code Playgroud)

当命令运行时,memcache.php文件根本没有改变?

dan*_*uer 30

您可以使用双引号单引号替换sed命令中的单引号.shell将单引号视为结束字符串.所以,就这样吧.你有过

sed -i 's/'ADMIN_USERNAME','memcache'/'ADMIN_USERNAME','u'/g' /var/www/html/memcache.php
Run Code Online (Sandbox Code Playgroud)

但是,如果用'''''替换'在sed命令中',那么shell将看到第一个'结束第一个单引号字符串,然后"'"作为双引号单引号,然后是最后一个'作为一个新的单引号字符串的开头.那就是

sed -i 's/'"'"'ADMIN_USERNAME'"'"','"'"'memcache'"'"'/'"'"'ADMIN_USERNAME'"'"','"'"'u'"'"'/g' /var/www/html/memcache.php
Run Code Online (Sandbox Code Playgroud)

出于同样的原因,你也应该能够在命令中代替'\''.

sed -i 's/'\''ADMIN_USERNAME\'',\''memcache\''/\''ADMIN_USERNAME\'',\''u\''/g' /var/www/html/memcache.php
Run Code Online (Sandbox Code Playgroud)

但实际上,使用替代机制会更好.我建议将源和目标字符串定义为变量,然后将它们放在sed字符串中.

SRC="'ADMIN_USERNAME','memcache'"
DST="'ADMIN_USERNAME','u'"
sed -i "s/$SRC/$DST/g" /var/www/html/memcache.php
Run Code Online (Sandbox Code Playgroud)

这样的方式更具可读性,它使您可以更轻松地以一个大小合适的块的方式处理引用的混乱.是的"shell变量内容不受文字扩展的影响,除非你强迫它"知识.:)

但是,请确保您没有在$ SRC或$ DST变量中放入/.;)


Pau*_*ce. 11

例如,您必须使用十六进制转义来执行这些替换.

$ echo "'foo'" | sed 's/\x27foo\x27/\x27bar\x27/'
'bar'
Run Code Online (Sandbox Code Playgroud)

你也可以使用八进制转义符:( \o047这是一个小写的"哦")或十进制转义:\d39.


Jon*_*ler 6

要了解如何执行此操作,您需要了解shell如何搞乱引号和反斜杠以及是否sed弄乱它们.

通常,shell中最容易使用单引号 - 除非正则表达式必须匹配单引号.单引号内没有特殊字符; 下一个单引号结束了它.双引号要​​难得多; 反斜杠,美元和背引号都很特别.

第一个要求最好用单引号sed表达式处理:

更改:

[server]
server[] = "localhost:11211"
Run Code Online (Sandbox Code Playgroud)

[server]
server[] = "localhost:11211"
server[] = "localhost:11212"
Run Code Online (Sandbox Code Playgroud)

为此,我们可以使用:

-e '/^server\[] = "localhost:11211"/{p;s/11211/11212/}'
Run Code Online (Sandbox Code Playgroud)

shell简单地将单引号内的所有内容发送到sed未触及的内容.唯一特殊的角色sed是开放式方括号.这将启动一个字符类,除了它之前的反斜杠.当你在一个字符类中时,紧密的方括号只是特殊的,所以它不需要转义.识别该行的动作是打印原件,然后11212替换11211; 默认打印将打印修改后的行.

另一部分有点棘手.因为模式包含单引号,所以我们最好在正则表达式周围使用双引号.

更改:

define('ADMIN_USERNAME','username');    // Admin Username
define('ADMIN_PASSWORD','password');    // Admin Password

$MEMCACHE_SERVERS[] = 'mymemcache-server1:11211'; // add more as an array
$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array
Run Code Online (Sandbox Code Playgroud)

至:

define('ADMIN_USERNAME','myusername');  // Admin Username
define('ADMIN_PASSWORD','mypassword');      // Admin Password

$MEMCACHE_SERVERS[] = 'localhost:11211'; // add more as an array
$MEMCACHE_SERVERS[] = 'localhost:11212'; // add more as an array
Run Code Online (Sandbox Code Playgroud)

前两行可能使用单个正则表达式进行映射:

-e "s/^\(define('ADMIN_[A-Z]\{0,8\}','\)\([^']*'\)/\1my\2/"
Run Code Online (Sandbox Code Playgroud)

这捕获了两个部分 - define('ADMIN_USERNAME','as \1username'as \2,以及my两个部分之间的替换位置.这不是太糟糕; shell不会对任何字符做任何特殊操作,因此您只需sed在双引号内键入要查看的内容即可.

最后两行比较棘手:

-e "s/^\(\$MEMCACHE_SERVERS\[] = '\)[^:]*\(:[0-9]*'\)/\1localhost\2/"
Run Code Online (Sandbox Code Playgroud)

但是,并不是那么棘手; 你只需要阻止shell扩展$MEMCACHE_SERVERS为一个shell变量,这就是为什么在前面有一个反斜杠$.方括号需要sed像以前一样保护.正则表达式匹配所有不是冒号的东西并替换它localhost.

所以,这个脚本应该工作:

sed -e '/^server\[] = "localhost:11211"/{p;s/11211/11212/}' \
    -e "s/^\(define('ADMIN_[A-Z]\{0,8\}','\)\([^']*'\)/\1my\2/" \
    -e "s/^\(\$MEMCACHE_SERVERS\[] = '\)[^:]*\(:[0-9]*'\)/\1localhost\2/" \
    "$@"
Run Code Online (Sandbox Code Playgroud)

但是,我只解释了为什么它应该起作用; 我没有证明它确实有效!