2017-10-12 1 views
1

ich folgendes gelesen haben:Linux Mit Variable ersetzen Doppel Containing Zitate

Ich habe gelernt, dass ich sed "s/STRING/$var1/g" können eine Zeichenfolge mit ersetzen der Inhalt einer Variablen Es fällt mir jedoch schwer, herauszufinden, wie man mit einer Variablen ersetzt, die doppelte Anführungszeichen, Klammern und Ausrufezeichen enthält.

Dann, in der Hoffnung, die Zitate zu entkommen, versuchte ich mein Ergebnis obwohl sed 's/\"/\\\"/g', die mir einen anderen Fehler sed: -e expression #1, char 7: unknown command: E' gab. Ich hatte gehofft, den problematischen Charakteren zu entkommen und dann den variablen Ersatz zu machen: sed "s/STRING/$var1/g". Aber ich konnte auch nicht so weit kommen.

Ich dachte, Sie könnten eine bessere Möglichkeit kennen, eine Zeichenfolge durch eine Variable zu ersetzen, die Anführungszeichen enthält.

File1.txt:

Example test here 
<tag>"Hello! [world]" This line sucks!</tag> 
End example file 

Variable:

var1=$(cat file1.txt) 

Beispiel:

echo "STRING" | sed "s/STRING/$var1/g" 

gewünschte Ausgangs:

Example test here 
<tag>"Hello! [world]" This line sucks!</tag> 
End example file 
+0

'sed' ist das nicht das richtige Werkzeug für diese Substitution. – anubhava

+0

@anubhava Ich sehe. Danke für den Rat Anubhava. Ich bin offen für alles, was funktioniert. Werde versuchen, mehr Forschung zu machen. Bearbeiten Sie die Frage, um das zu berücksichtigen. – DomainsFeatured

+0

@batMan ja, das ist die Idee. Um die Daten in der Variablen gleich zu halten. Ich möchte "STRING" durch den Inhalt von "$ var1" ersetzen. Da stecke ich fest. Dies ist nur ein minimalistisches Beispiel. – DomainsFeatured

Antwort

2

awk

$ echo "STRING" | awk -v var="$var1" '{ gsub(/STRING/,var,$0); print $0}' 
Example test here 
<tag>"Hello! [world]" This line sucks!</tag> 
End example file 

-v var="$var1" mit: global Ersatz alle Vorkommen von "STRING" in ganzer Platte $0 mit var

Sonderfall: "Um Shell-Variable in awk
gsub(/STRING/,var,$0) verwenden Wenn Ihr var& drin hat, sagen Sie am Anfang der Zeile, dann wird es Probleme mit gsub als & hat besondere Bedeutung und bezieht sich stattdessen auf den übereinstimmenden Text.

mit dieser Situation umgehen wir haben & zu entkommen, wie folgt:

$ echo "STRING" | awk -v var="$var1" '{ gsub(/&/,"\\\\&",var); gsub(/STRING/,var,$0);print $0}' 
&Example test here 
<tag>"Hello! [world]" This line sucks!</tag> 
End example file 
+0

Danke @batMan. Das funktioniert für mich. Du bist mein Held. – DomainsFeatured

+1

@DomainsFeatured: :) – batMan

+0

In vielen Fällen wird dies nicht funktionieren. .z.B. wenn '$ var1' '& 'character irgendwo enthält. – anubhava

2

Das Problem ist nicht die Anführungszeichen ist. Sie vermissen den Befehl "s", der sed als /STRING/ als Zeilenadresse behandelt, und den Wert $var1 als Befehl, der auf übereinstimmenden Zeilen ausgeführt werden soll. $var1 hat außerdem Zeilenumbrüche und ein Zeichen /, das Probleme bei der Ersetzung verursachen wird. So fügen Sie das "s", und die Flucht der entsprechenden Zeichen in $var1:

var1escaped="$(echo "$var1" | sed '[email protected][\/&]@\\&@; $ !s/$/\\/')" 
echo "STRING" | sed "s/STRING/$var1escaped/" 

... aber realistisch, @ Batmans Antwort (mit awk) ist wahrscheinlich eine bessere Lösung.Hier

+0

Hoppla. Ich habe es mit dem "s" laufen lassen, aber es hat auch nicht funktioniert. Deine Antwort funktioniert! Es ist schön, die Hintergrundinformationen für Lernzwecke zu haben. Deine Fähigkeiten, diesen anderen Charakteren zu entkommen, sind meisterhaft. – DomainsFeatured

+0

@ Gordon-Davisson: das ist wirklich hilfreich. Können Sie erklären, Bit Ihres zweiten Teils, d. H. '$! S/$/\\/'' – batMan

+0

@batMan Dieser Teil entkernt die Zeilenumbrüche * außer * der am Ende der Datei (/ String). Offen gesagt, es ist ziemlich chaotisch. 'echo' fügt dem Ende der Variablen beim Drucken eine neue Zeile hinzu; In 'sed' gilt die' $! '- Adresse für alle bis auf die letzte Zeile der Datei, und'/$/\\/'fügt am Ende der Zeile einen umgekehrten Schrägstrich ein (der Backslash wird verdoppelt, weil er es muss) selbst entkommen sein ...). Beachten Sie, dass '$' hier zwei verschiedene Rollen spielt - in der Zeilenadresse entspricht es der letzten Zeile; im Ersatzmuster entspricht es dem Ende der Zeile. Dann, nach all dem, löscht '$()' den letzten Zeilenumbruch. –

1

ist ein awk-Befehl, wird Text-to-be-ersetzt von einer Datei, die von allen Arten von Sonderzeichen wie & oder \ usw. bestehen kann:

awk -v pat="STRING" 'ARGV[1] == FILENAME { 
    # read replacement text from first file in arguments 
    a = (a == "" ? "" : a RS) $0 
    next 
} 
{ 
    # now run a loop using index function and use substr to get the replacements 
    s = "" 
    while(p = index($0, pat)) { 
     s = s substr($0, 1, p-1) a 
     $0 = substr($0, p+length(pat)) 
    } 
    $0 = s $0 
} 1' File1.txt <(echo "STRING") 

Um in der Lage sein, alle zu handhaben Art von Sonderzeichen Dieser Befehl vermeidet alle auf Regex basierenden Funktionen. Wir verwenden Klartext-basierte Funktionen wie index, substr usw.

+1

Das ist eine Menge! Aber, sehr nützlich! Danke @Anubhava :-) – DomainsFeatured