Ich habe einige Möglichkeiten gefunden, externe Shell-Variablen an ein awk
-Skript zu übergeben, aber ich bin über '
und "
verwirrt.
Zuerst versuchte ich es mit einem Shell-Skript:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Dann probierte awk:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Warum ist der Unterschied?
Zum Schluss habe ich folgendes 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 darüber verwirrt.
awk
ladenkann auf verschiedene Weise erfolgen. Einige sind besser als andere. Dies sollte die meisten von ihnen abdecken. Wenn Sie einen Kommentar haben, lassen Sie ihn bitte unten.
Es verwendet die -v
-Option: (P.S. verwendet ein Leerzeichen nach -v
oder ist weniger portabel. Beispiel: awk -v var=
nicht awk -vvar=
)
variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
Dies sollte mit den meisten awk
kompatibel sein und die Variable ist auch im BEGIN
-Block verfügbar:
Wenn Sie mehrere Variablen haben:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Warnung. Wie Ed Morton schreibt, werden Escape-Sequenzen interpretiert, sodass \t
eine echte tab
und nicht \t
wird, wenn Sie danach suchen. Kann mit ENVIRON[]
gelöst oder über ARGV[]
aufgerufen werden
Hier bekommen wir die Variable nach dem awk
-Code. Dies funktioniert gut, solange Sie die Variable im BEGIN
-Block nicht benötigen:
variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
Dies funktioniert auch mit mehreren Variablen awk '{print a,b,$0}' a="$var1" b="$var2" file
Die Verwendung von Variablen auf diese Weise funktioniert nicht im BEGIN
-Block:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Variable kann auch zu awk
hinzugefügt werden, indem Sie hier string verwenden.
awk '{print $0}' <<< "$variable"
test
Das ist das Gleiche wie:
echo "$variable" | awk '{print $0}'
PS, dies bedroht die Variable als Dateieingabe
Beim TrueY-Schreiben können Sie die Variable ENVIRON
verwenden, um den Code Environmental Variables
.__ zu drucken. Wenn Sie vor dem Ausführen von AWK eine Variable setzen, können Sie sie wie folgt ausdrucken:
X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["Shell"]}'
MyVar /bin/bash
Während Steven Penny schreibt, können Sie ARGV
verwenden, um das Data-Inn in den Hintergrund zu bringen.
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
Um den Data Inn zum Code selbst zu bringen, nicht nur zum BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Sie können eine Variable innerhalb des awk
-Codes verwenden, die jedoch unlesbar und schwer lesbar ist, und wie Charles Duffy
darauf hinweist, kann diese Version auch Opfer einer Code-Injektion werden. Wenn jemand der Variablen fehlerhaftes Material hinzufügt, wird dies als Teil des awk
-Codes ausgeführt.
Dies funktioniert durch Extrahieren der Variablen im Code, sodass sie Teil davon wird.
Wenn Sie eine awk
erstellen möchten, die sich dynamisch mit Hilfe von Variablen ändert, können Sie dies auf folgende Weise tun: Bot verwendet sie NICHT für normale Variablen.
variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Hier ist ein Beispiel für die Code-Injektion:
variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
Sie können auf diese Weise viele Befehle zu awk
hinzufügen. Sogar mit ungültigen Befehlen zum Absturz bringen.
Verwendung von Anführungszeichen
Es ist immer gut, die Anführungszeichenvariable "$variable"
zu verdoppeln.
Wenn dies nicht der Fall ist, werden mehrere Zeilen als lange einzelne Zeile hinzugefügt.
Beispiel:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Andere Fehler können Sie ohne Anführungszeichen erhalten:
variable="line one\nline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ syntax error
Bei einfachen Anführungszeichen wird der Wert der Variablen nicht erweitert:
awk -v var='$variable' 'BEGIN {print var}'
$variable
Weitere Informationen zu AWK und Variablen
Lesen Sie diese FAQ
Es scheint, dass der eingebaute Hash aus ENVIRON
awk überhaupt nicht erwähnt wird. Ein Beispiel für seine Verwendung:
$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
Verwenden Sie eine dieser Optionen, je nachdem, wie Sie umgekehrte Schrägstriche in den Shell-Variablen bearbeiten möchten (avar
ist eine awk-Variable, svar
ist eine Shell-Variable)
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
Siehe http://cfajohnson.com/Shell/cus-faq-2.html#Q24 für Einzelheiten und andere Optionen. Die erste Methode oben ist fast immer die beste Option und hat die offensichtlichste Semantik.
Sie können die Befehlszeilenoption-v
mit einem Variablennamen (v
) und einem Wert (=
) der Umgebungsvariablen ("${v}"
) übergeben:
% awk -vv="${v}" 'BEGIN { print v }'
123test
Oder um es klarer zu machen (mit weit weniger v
s):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
Sie können ARGV nutzen:
v=123test
awk 'BEGIN {print ARGV[1]}' "$v"
Beachten Sie, dass Sie, wenn Sie in den Körper einsteigen möchten, anpassen müssen ARGC:
awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
for i in chr{1..22} chrX chrY
do
awk -v chr="$i" '$1==chr' ../snp150.hg19.txt >> $chr.vcf.bed
echo $i
done
Ich musste ein Datum am Anfang der Zeilen einer Protokolldatei einfügen und es wird wie folgt ausgeführt:
DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log
Es kann zum Speichern in eine andere Datei umgeleitet werden
Ich habe gerade @ Jotnes Antwort auf "for loop" geändert.
for i in `seq 11 20`; do Host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done