2017-12-21 18 views
1

ich den Eingang zu ersetzen,Bash: Suchen und Ersetzen mit Parametern Expansion nur

input_string: @include Kreis-Fortschritt (38px, 30px, # 4eb630)

und Ausgang,

Output_string : @include circle-progress (38px, 30px)

mit ${input_string//pattern/replacement_string} wo Muster ist , #[A-Fa-f0-9]{3,6} ich liefern.

Dieses Muster entspricht den Teil I ersetzt werden soll, wenn ich es in regex101.com testen, aber den Code

replace_pat=", \#[A-Fa-f0-9]{3,6}" 
echo "${input_string//"$replace_pat"/}" 

Ausgänge genau der gleiche Eingang. Ich möchte nichts anderes als sed verwenden. Ich weiß nicht, wo ich falsch liege.

Gelöst. Danke Gordon.

Die Lösung mit Glob-Mustern funktioniert einwandfrei, aber der Code unten druckt immer noch genau den gleichen Eingang, nämlich line passend pattern, wenn ich Zeilen Code aus einer Datei lesen.

pattern="@include circle-progress\(([0-9]{1,3}px,){2}#[A-Fa-f0-9]{3,6}\)" replace_glob=', #[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9])))' while IFS='' read -r line || [[ -n "$line" ]]; do if [[ $line =~ $pattern ]] then echo "${line//$replace_glob/}" fi done < "$1"

Antwort

2

Das Muster Ersatz Sie verwenden (${var//pattern/replacement}) verwendet glob patterns, nicht reguläre Ausdrücke . Glob-Patterns sind deutlich weniger leistungsfähig als reguläre Ausdrücke (und haben eine sehr unterschiedliche Syntax), so dass Sie nicht genau das tun können, was Sie versuchen. Nun, es sei denn, Sie verwenden bash (keine generische POSIX-Shell) und aktivieren erweiterte Glob-Patterns. Ihre Syntax unterscheidet sich sehr von regulären Ausdrücken, aber sie sind tatsächlich genauso mächtig (aber manchmal unelegant). Hier ist, wie dies in bash zu tun:

shopt -s extglob # Enable extended glob pattern syntax 
replace_glob=', #[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9]?([A-Fa-f0-9])))' 
input_string='@include circle-progress(38px, 30px, #4eb630)' 
echo "${input_string//$replace_glob/}" # prints "@include circle-progress(38px, 30px)" 

Habe ich erwähnt, dass erweiterte Globs unelegant sein können? Sie sind besonders schlecht bei begrenzten Wiederholungen ({3,6} im regulären Ausdruck, was zwischen 3 und 6 des vorhergehenden Punkts bedeutet). Der obige Glob beginnt mit ", #" (offensichtlich), dann drei "[A-Fa-f0-9]", dann ein optionales (angezeigt durch ?()) Muster, das eine weitere hexadezimale Ziffer und eine optionale Zeichenkette enthält, die .. Nun, du hast die Idee. Wenn Sie es vereinfachen wollen und nur eine beliebige Anzahl von Hex-Stellen erlauben, dann wird es viel einfacher:

replace_glob=', #*([A-Fa-f0-9])' 

(BTW, auch beachten Sie, dass ich nicht doppelt zitieren die Mustervariable, wenn Sie es - das ist weil die Shell in Anführungszeichen gesetzte Muster (oder Teile von Mustern) als Literalstrings behandelt, wobei die Globsyntax ignoriert wird. Dies ist einer der wenigen Fälle in der Shell, in dem Sie Variablenreferenzen nicht doppelt zitieren sollten.)

0
[[email protected] ~]# a="@include circle-progress(38px, 30px**, #4eb630**)"; echo $a | sed 's/\*\*,.*/)/g' 
@include circle-progress(38px, 30px) 
0

könnten Sie verwenden:

str='input_string: @include circle-progress(38px, 30px, #4eb630)'; echo ${str/, #[A-Fa-f0-9]*/)} 

oder mit sed:

echo 'input_string: @include circle-progress(38px, 30px, #4eb630)' | sed 's/, #[A-Fa-f0-9]\{3,6\}//'