2

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 escaping 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
ChrisSM
  • 90
  • 5
  • your escape slashes look a bit backwards to me (should be ` \ ` not `/`). and inside a single quoted string, variables will not interpolate anyway, so a number of the escapes you have are redundant – Eric Strom Jun 09 '10 at 19:41
  • erm. but this works (apologies for no pretty-print): $ echo ${X} | sed -e 's/\\/\\\\/g' ; # a\\.b ; $ sed -e '/a\\.b/,/\;\;/d' t.sh ; $cat t.sh ; case N in ; esac ; Which is the desired effect. The idea is to get a shell-friendly string into the sed programatically rather than interactively as above. That's where the apparently redundant escapes (which are \, the "/" are for sed delimiting) come in. – ChrisSM Jun 09 '10 at 20:57

2 Answers2

0
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. :)

hobbs
  • 223,387
  • 19
  • 210
  • 288
0

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.

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439