rimozione di una clausola case: espansione bash in regexp sed: X = 'un \ .b'; Y = ';;' sed -n '/ $ {X} /, / $ {} Y / d'

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

Domanda

Sto cercando di rimuovere una clausola caso da uno script bash. La clausola può variare, ma avrà sempre backslash come parte della stringa caso-partita.

Cercavo sed ma potrebbe usare awk o perl one-liner all'interno dello script bash.

L'obiettivo della modifica è semplice, assomiglia:

 $cat t.sh
 case N in 
 a\.b); 
   #[..etc., varies] 
 ;;
 esac

Sono in esecuzione afoul di espansione variabile di fuga backslash, virgola o entrambi. Se 'eval' io la spoglierò mie fughe backslash. Se non lo faccio, i punti e virgola mi recuperare. Così ho cercato di espansione all'interno della subshell sed. Questo falli l'interprete come ho scritto. Più sfuggire alle punti e virgola non sembra aiuto.

X='a\.b' ; Y=';;'   
sed -i '/$(echo ${X} | sed -n 's/\\/\\\\/g')/,/$(echo ${Y} | sed -n s/\;/\\;/g')/d t.sh

E questo:

perl -i.bak -ne 'print unless /${X}/ .. /{$Y}/' t.sh  # which empties t.sh

e

eval perl -i.bak -ne \'print unless /${X}/ .. /{$Y}/' t.sh  # which does nothing
È stato utile?

Soluzione

printf di Bash ha una caratteristica citando che aiuterà:

X='a\.b'; Y=';;'
sed "/$(printf "%q" "$X")/,/$(printf "%q" "$Y")/d" t.sh

oppure è possibile utilizzare in aggiunta la funzione di assegnazione variabile printf:

printf -v X "%q" 'a\.b'
printf -v Y "%q" ';;'
sed "/$X/,/$Y/d" t.sh

Si noti l'uso di doppi apici l'argomento del comando sed. apici singoli impediranno l'espansione delle variabili e sostituzione di comando. Quando non vengono utilizzati quelli, però, di solito è meglio usare le virgolette singole.

Altri suggerimenti

X='a\.b'
Y=';;'
perl -i.bak -ne 'print unless /\Q'$X'/ .. /\Q'$Y'/' t.sh

Questa è giocare con guscio citando, ma funziona abbastanza bene. :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top