Ich habe einige Möglichkeiten gefunden, externe Shell-Variablen an ein awk
Skript zu übergeben, bin aber verwirrt über '
und "
.
Zuerst habe ich es mit einem Shell-Skript versucht:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Dann versuchte awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Warum ist der Unterschied?
Zuletzt habe ich das versucht:
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
Ich bin verwirrt darüber.
/var/
. Verwenden Sie stattdessen Tilde:awk -v var="$var" '$0 ~ var'
Antworten:
Verwenden
-v
(Der beste Weg, am tragbarsten)Verwenden Sie die
-v
Option: (PS verwenden ein Leerzeichen nach-v
oder es wird weniger portabel sein. ZBawk -v var=
nichtawk -vvar=
)Dies sollte mit den meisten kompatibel sein
awk
, und die Variable ist auch imBEGIN
Block verfügbar :Wenn Sie mehrere Variablen haben:
Warnung . Wie Ed Morton schreibt, werden Escape-Sequenzen so interpretiert, dass sie
\t
real werdentab
und nicht,\t
wenn Sie danach suchen. Kann durch VerwendungENVIRON[]
oder Zugriff über gelöst werdenARGV[]
PS Wenn Sie drei vertikale Balken als Trennzeichen mögen
|||
, können diese nicht maskiert werden. Verwenden Sie sie daher-F"[|][|][|]"
Variable nach Codeblock
Hier erhalten wir die Variable nach dem
awk
Code. Dies funktioniert einwandfrei, solange Sie die Variable imBEGIN
Block nicht benötigen :awk '{print a,b,$0}' a="$var1" b="$var2" file
FS
für jede Datei ein anderes Feldtrennzeichen festlegen .awk 'some code' FS=',' file1.txt FS=';' file2.ext
BEGIN
Block:echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Here-String
Eine Variable kann auch zur
awk
Verwendung einer Here-Zeichenfolge aus Shells hinzugefügt werden , die sie unterstützen (einschließlich Bash):Dies ist das gleiche wie:
PS Dies behandelt die Variable als Dateieingabe.
ENVIRON
EingangWährend TrueY schreibt, können Sie
ENVIRON
mit Umgebungsvariablen drucken . Wenn Sie eine Variable festlegen, bevor Sie AWK ausführen, können Sie sie wie folgt ausdrucken:ARGV
EingangWie Steven Penny schreibt, können Sie verwenden
ARGV
, um die Daten in awk zu bringen:Um die Daten in den Code selbst zu übertragen, nicht nur den BEGIN:
Variable innerhalb des Codes: USE WITH CAUTION
Sie können eine Variable im
awk
Code verwenden, diese ist jedoch unübersichtlich und schwer zu lesen. Wie bereits erwähntCharles Duffy
, ist diese Version möglicherweise auch Opfer einer Code-Injektion. Wenn jemand der Variablen schlechtes Material hinzufügt, wird es als Teil desawk
Codes ausgeführt.Dies funktioniert durch Extrahieren der Variablen innerhalb des Codes, sodass sie ein Teil davon wird.
Wenn Sie eine
awk
erstellen möchten, die sich bei Verwendung von Variablen dynamisch ändert, können Sie dies auf diese Weise tun, aber NICHT für normale Variablen verwenden.Hier ist ein Beispiel für die Code-Injection:
Sie können auf
awk
diese Weise viele Befehle hinzufügen . Lassen Sie es sogar mit ungültigen Befehlen abstürzen.Zusatzinformation:
Verwendung von doppelten Anführungszeichen
Es ist immer gut, die Variable in doppelte Anführungszeichen zu setzen.
"$variable"
Wenn nicht, werden mehrere Zeilen als lange einzelne Zeile hinzugefügt.
Beispiel:
Andere Fehler, die Sie ohne doppeltes Anführungszeichen erhalten können:
Bei einfachen Anführungszeichen wird der Wert der Variablen nicht erweitert:
Weitere Informationen zu AWK und Variablen
Lesen Sie diese FAQ .
quelle
awk -v repo="$1" -v tag="$2" 'BEGIN {print "repo="repo,"tag="tag}'
. Es wird angezeigt, ob die Variable gedruckt wird. Stellen Sie eine eigene Frage, wenn Sie das nicht herausfinden können.Es scheint, dass der gute Alte
ENVIRON
awkeingebauter Hash wird überhaupt nicht erwähnt. Ein Beispiel für seine Verwendung:quelle
-v
funktioniert nicht, wenn der Wert Backslashes enthält.awk -v x='\c\d' ...
, wird es richtig benutzt. Aber wennx
gedruckt wird, lässt awk die berühmteawk: warning: escape sequence '\c' treated as plain 'c'
Fehlermeldung fallen ... Danke!-v
so konzipiert wurde, dass Sie es\t
in der Variablen verwenden und es beispielsweise mit einer Literal-Registerkarte in den Daten abgleichen können. Wenn dies nicht das gewünschte Verhalten ist, verwenden-v
SieARGV[]
oder nichtENVIRON[]
.Verwenden Sie
avar
eine dieser Optionen, je nachdem, wie Backslashes in den Shell-Variablen behandelt werden sollen ( ist eine awk-Variable,svar
ist eine Shell-Variable):Weitere Informationen und andere Optionen finden Sie unter http://cfajohnson.com/shell/cus-faq-2.html#Q24 . Die erste Methode oben ist fast immer die beste Option und hat die offensichtlichste Semantik.
quelle
Sie können die Befehlszeilenoption
-v
mit einem Variablennamen (v
) und einem Wert (=
) der Umgebungsvariablen ("${v}"
) übergeben:Oder um es klarer zu machen (mit weit weniger
v
s):quelle
Sie können ARGV verwenden:
Beachten Sie, dass Sie ARGC anpassen müssen, wenn Sie mit dem Körper fortfahren möchten:
quelle
Ich habe gerade @ Jotnes Antwort für "for loop" geändert.
quelle
-v
Option von Awk zu sein, die bereits in vielen der vorhandenen Antworten erwähnt wurde. Wenn Sie zeigen möchten, wie Awk in einer Schleife ausgeführt wird, ist das wirklich eine andere Frage.Ich musste das Datum am Anfang der Zeilen einer Protokolldatei einfügen und es geschieht wie folgt:
Es kann zum Speichern in eine andere Datei umgeleitet werden
quelle