removing a case clause: bash expansion in sed regexp: X='a\.b' ; Y=';;' sed -n '/${X}/,/${Y}/d'

StackOverflow https://stackoverflow.com/questions/3009202

문제

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
도움이 되었습니까?

해결책

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top