0

I have a file named 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

Having studied the answers to this worthy question, I've tried to implement the solutions in a script that is meant to comment out with # a couple of lines:

#!/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

Why don't semicolons and newlines work with -E when giving multiple expressions to GNU sed?

P.S. Because of distinct workings of sed with -E I don't consider this question duplicate to the one referenced above.

  • 2
    \(...\) must be changed to (...) with -E. -E only changes the type of the regular expressions used by sed. Also note that sed 's/\(...\)/#\1/ (or sed -E 's/(...)/#\1/') can be written sed 's/.../#&/' – Stéphane Chazelas Jul 30 '22 at 09:04
  • @StéphaneChazelas Thanks. I realized that I was unnecessarily escaping . sed -E 's/^(debug=tor)/#\1/;s/^(onlynet=onion)/#\1/;s/^(proxy=127)/#\1/' bitcoin.conf works fine. Would you decode ... in your sed commands? – John Smith Jul 30 '22 at 09:39
  • 1
    In general, it helps if you also explain what you want the commands to do. Yes, we can figure it out from the code sometimes, but since the code isn't working (otherwise there wouldn't be a question), it is often hard to understand what the asker wants. You have given us a file with loads of commands and don't tell us what you expect any of them to do. – terdon Jul 30 '22 at 12:23
  • @terdon I've just modified the question in response to your comment. – John Smith Jul 30 '22 at 12:50

2 Answers2

3

The issue is you are adding the ERE flag to enable extended functionality but using BRE syntax. Even if you removed the flag, as you have also escaped the returning back reference, it will replace the line with 1.

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

The code above escapes the parenthesis therefore making it literal. As no match is found, nothing is changed.

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

Added by Ed Morton - by not quoting the script (a bad idea!) it's exposed to the shell for interpretation before sed sees it so the shell is consuming all the leading backslashes and so what sed sees is s/^(debug=tor)/#\1/ -e s/^(onlynet=onion)/#\1/ -e s/^(proxy=127)/#\1/

To answer your question, using semi colons for multiple commands does work with -E flag as demonstrated in your first attempt but no match was made. Here is a working example.

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

However, you could also use & to return the match as nothing is being excluded making the group matching redundant. As it will not use back referencing or metachars, there is also really no need for extended functionality.

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

Or even better - Added by Ed Morton

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

HatLess already explained why your approaches weren't working, but if all you want is to comment a line if it starts with a certain string, you can slo use this syntax:

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

Which means "if this line starts with string, then replace old with new. So you could write your command as:

sed -E '/^(debug=tor|onlynet=onion|proxy=127)/s/^/#/' file
terdon
  • 242,166