variablen Text nach einem anderen variablen Text in einer bestimmten Zeile einfügen

variablen Text nach einem anderen variablen Text in einer bestimmten Zeile einfügen

Ich versuche, in einer bestimmten Zeile variablen Text nach einem anderen variablen Text einzufügen. Unten ist mein bisheriger Versuch, soweit ich das beurteilen kann. Wenn ich die Anführungszeichen umgehen kann, sodass awkdie Variable sichtbar ist und trotzdem angewendet werden kann, sollte es funktionieren, aber ich habe keine Ahnung, wie das geht:

#!/bin/sh

VAR=$(head -n1 ~/Scripts/tmp/file.txt)
VAR1=$(head -n1 ~/Scripts/tmp/file1.txt)

awk '/$VAR/ { print; print "$VAR1"; next }1' ~/Scripts/tmp/file.txt

Antwort1

Um Zeichenfolgen an ein Awk-Skript zu übergeben, übergeben Sie sie über Umgebungsvariablen.

export VAR VAR1
awk '
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

Ich habe Ihr Skript neu organisiert, um die Logik einfacher zu machen. Außerdem habe ich die Regexp-Übereinstimmung durch einen Zeichenfolgenvergleich ersetzt: Mit der Regexp-Übereinstimmung $VARwürde es als regulärer Ausdruck behandelt, es würde keinen Zeichenfolgenvergleich durchführen. Und es /$VAR/würde nicht einmal den Wert von verwenden VAR(das ist Perl-Syntax, nicht awk), den Sie match($0, VAR)dafür benötigen würden.

Ein Hinweis zu einigen anderen Lösungen, die nicht wirklich funktionieren (sie funktionieren nur, wenn die Variablen keine Sonderzeichen enthalten; welches Zeichen ein Sonderzeichen ist, hängt von der Methode ab):

  • awk -v awkvar="$VAR" '$0 == awkvar …'erweitert Backslashes im Zeileninhalt.
  • awk "/$VAR/" …lässt die Shell den Wert VARals Awk-Snippet erweitern. Wenn beispielsweise file.txtenthält , wird ^/ {system("touch ~/naughty")} /der Befehl touch ~/naughtyausgeführt.

Ein alternativer Ansatz besteht darin, awk alle Dateien lesen zu lassen.

awk '
    BEGIN { VAR1 = getline <"~/Scripts/tmp/file1.txt"; }
    NR == 1 {VAR = $0}
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

Antwort2

Eine mögliche AWK-Lösung:

   awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'

Trennen Sie die Anführungszeichen um alle Ihre externen Variablen.

Eine andere mögliche Lösung, wie sie im anderen Beitrag zur Übergabe von Variablen vorgeschlagen wird, besteht darin, VAR1 als AWK-Variable zu übergeben. Ich denke jedoch, dass Sie für das Muster mithilfe von VAR trotzdem den Block mit einfachen Anführungszeichen escapen müssen:

 awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'

Sie könnten stattdessen sed ausprobieren :), es ist speziell für diese Art der Ersetzung konzipiert.

 sed "s/$VAR.*/\0\n$VAR1/" ~/Scripts/tmp/file.txt     

Wenn Sie mehrere Instanzen von VAR in einer einzigen Zeile haben können, fügen Sie am Ende des sed-Befehls (global) g hinzu, damit er nicht bei der ersten gefundenen Übereinstimmung anhält:

 sed "s/$VAR.*/\0 $VAR1/g" ~/Scripts/tmp/file.txt 

WICHTIG!: Stellen Sie sicher, dass das Zeichen „/“ nicht in der Variable VAR oder VAR1 vorkommt. Wenn dies möglich ist, müssen Sie es für awk oder sed maskieren. Alternativ können Sie bei sed das Trennzeichen für den Befehl in etwas anderes wie „;“ ändern, zum Beispiel:

 sed "s;$VAR.*;\0\n$VAR1;" ~/Scripts/tmp/file.txt

Erklärung des sed-Befehls:
Wir verwenden um den sed-Befehl herum doppelte Anführungszeichen anstelle von einfachen Anführungszeichen, damit Variablen wie VAR und VAR1 durch ihre Werte ersetzt werden. Dies geschieht, bevor der Befehl von sed ausgeführt wird, weshalb Sie, falls / im Variableninhalt vorhanden sein kann, darauf zugreifen müssen (dies gilt auch für awk).
Das „s“ gibt an, dass Sie einen Ersetzungsbefehl in der Form schreiben:
s/<Muster>/<Ersetzungsmuster>/.
Das „/“ unmittelbar nach dem s ist das Trennzeichen, das zum Trennen der Befehlsabschnitte verwendet wird. Wenn Sie also ; eingeben, müssen Sie überall ; verwenden, wie oben gezeigt. Das abzugleichende Muster ist der Inhalt der Variable $VAR. Das Ersetzungsmuster ist \0, was bedeutet, dass das, was dem Muster entspricht, in einer neuen Zeile „\n“ und dem Inhalt von VAR2 gedruckt wird.

UPS, habe den Teil über die Zeile unten nicht gesehen … feste Muster.

Antwort3

Wenn Sie verwenden möchten awk, müssen Sie die bashVariable awkmit der -vOption übergeben:

awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt

Für eine korrektere und detailliertere Lösung lesen Sie bitte Robs Antwort.

verwandte Informationen