removing a case clause: bash expansion in sed regexp: X='a\.b' ; Y=';;' sed -n '/${X}/,/${Y}/d'
I'm trying to remove a case clause from a bash script. The clause will vary, but will always have backslashes as part of the case-match string.
I was trying sed but could use awk or a perl one-liner within the bash script.
The target of the edit is straightforward, resembles:
$cat t.sh
case N in
a\.b);
#[..etc., varies]
;;
esac
I am running afoul of the variable expansion es开发者_如何学Pythoncaping backslashes, semicolons or both. If I 'eval' I strip my backslash escapes. If I don't, the semi-colons catch me up. So I tried subshell expansion within the sed. This fouls the interpreter as I've written it. More escaping the semi-colons doesn't seem to help.
X='a\.b' ; Y=';;'
sed -i '/$(echo ${X} | sed -n 's/\\/\\\\/g')/,/$(echo ${Y} | sed -n s/\;/\\;/g')/d t.sh
And this:
perl -i.bak -ne 'print unless /${X}/ .. /{$Y}/' t.sh # which empties t.sh
and
eval perl -i.bak -ne \'print unless /${X}/ .. /{$Y}/' t.sh # which does nothing
Bash's printf
has a quoting feature that will help:
X='a\.b'; Y=';;'
sed "/$(printf "%q" "$X")/,/$(printf "%q" "$Y")/d" t.sh
or you can additionally use the printf
variable assignment feature:
printf -v X "%q" 'a\.b'
printf -v Y "%q" ';;'
sed "/$X/,/$Y/d" t.sh
Note the use of double quotes around the sed
command argument. Single quotes will prevent the expansion of variables and command substitution. When those aren't being used, though, it's usually best to use single quotes.
X='a\.b'
Y=';;'
perl -i.bak -ne 'print unless /\Q'$X'/ .. /\Q'$Y'/' t.sh
This is playing games with shell quoting, but it works pretty well. :)
精彩评论