当使用 -E 且不使用多个 -e 时,如何为 GNU sed 提供多个表达式?

当使用 -E 且不使用多个 -e 时,如何为 GNU sed 提供多个表达式?

我有一个名为bitcoin.conf

#Bind to given address and always listen on it (comment out when not using as a wallet):
#bind=127.0.0.1
daemon=1
#debug=i2p
debug=tor
#Pre-generate this many public/private key pairs, so wallet backups will be valid for
# both prior transactions and several dozen future transactions
keypool=2
#i2pacceptincoming=1

#i2psam=127.0.0.1:8060
#Make outgoing connections only to .onion addresses. Incoming connections are not affected by this option:
onlynet=i2p
onlynet=onion
#running Bitcoin Core behind a Tor proxy i.e. SOCKS5 proxy:
proxy=127.0.0.1:9050

研究了以下问题的答案后这个值得问的问题,我尝试在脚本中实现解决方案,该脚本旨在用#几行注释:

#!/usr/bin/bash

#Semicolons do not seem to work below.
#This gives me no error but it does not do anything 
#sed -Ee 's/^\(debug=tor\)/#\\1/;s/^\(onlynet=onion\)/#\\1/;s/^\(proxy=127\)/#\\1/' bitcoin.conf

#This works fine
sed -Ee s/^\(debug=tor\)/#\\1/ -e s/^\(onlynet=onion\)/#\\1/ -e s/^\(proxy=127\)/#\\1/ bitcoin.conf 

#When grouping, and therefore extended regexp, is not applied semicolons seem to work fine
sed -e 's/^debug=tor/#debug=tor/;s/^onlynet=onion/#onlynet=onion/;s/^proxy=127/#proxy=127/' bitcoin.conf 


##This gives me no error but it doesn't do anything
#sed -Ee 's/^\(debug=tor\)/#\\1/
#  s/^\(onlynet=onion\)/#\\1/ 
#  s/^\(proxy=127\)/#\\1/' bitcoin.conf 




#sed -i  -E -e 's/^\(debug=tor\)/#\\1/' -e 's/^\(onlynet=onion\)/#\\1/' -e 's/^\(proxy=127\)/#\\1/' \
#-e 's/^\(addnode\)/#\\1/' -e 's/^\(seednode\)/#\\1/' bitcoin.conf #does not comment out anything

-E为什么在向 GNU 提供多个表达式时分号和换行符不起作用sed

PS 由于sedwith的不同工作方式,-E我不认为这个问题与上面提到的问题重复。

答案1

问题是您正在添加ERE标志以启用扩展功能,但使用BRE语法。即使您删除了该标志,因为您也转义了返回引用,它也会将该行替换为1.

$ sed -Ee 's/^\(debug=tor\)/#\\1/;s/^\(onlynet=onion\)/#\\1/;s/^\(proxy=127\)/#\\1/'

上面的代码转义了括号,因此使其成为字面意思。由于未找到匹配项,因此没有任何更改。

$ sed -Ee s/^\(debug=tor\)/#\\1/ -e s/^\(onlynet=onion\)/#\\1/ -e s/^\(proxy=127\)/#\\1/

添加者埃德·莫顿- 通过不引用脚本(一个坏主意!),在 sed 看到它之前,它会暴露给 shell 进行解释,因此 shell 会消耗所有前导反斜杠,所以 sed 看到的是s/^(debug=tor)/#\1/ -e s/^(onlynet=onion)/#\1/ -e s/^(proxy=127)/#\1/

为了回答您的问题,对多个命令使用分号确实可以与-E标志一起使用,如您第一次尝试中所示,但没有匹配。这是一个工作示例。

$ sed -E 's/^(debug=tor)/#\1/;s/^(onlynet=onion)/#\1/;s/^(proxy=127)/#\1/'

但是,您也可以使用&返回匹配项,因为没有排除任何内容,从而使组匹配变得多余。由于它不会使用反向引用或元字符,因此实际上也不需要扩展功能。

$ sed 's/^debug=tor/#&/;s/^onlynet=onion/#&/;s/^proxy=127/#&/'

或者甚至更好 - 添加者埃德·莫顿

$ sed -E 's/^(debug=tor|onlynet=onion|proxy=127)$/#&/'

答案2

HatLess 已经解释了为什么你的方法不起作用,但如果你只想注释以某个字符串开头的行,你可以使用以下语法:

sed '/^string/s/old/new/' file

这意味着“如果此行以 开头string,则替换oldnew。因此您可以将命令编写为:

sed -E '/^(debug=tor|onlynet=onion|proxy=127)/s/^/#/' file

相关内容