Wenn awk empfängt"0"als Eingabe, verhält es sich in manchen Fällen anders. Code unten:
var=$1
echo ""; echo -n 'o/p of $1=$1 ==>'; echo $var | awk '$1=$1'
echo "";echo -n 'o/p of {$1=$1;print} ==>';echo $var | awk '{$1=$1;print}'
echo "";echo -n 'o/p of $1==$1 ==>';echo $var | awk '$1==$1'
echo "";echo -n 'o/p of {$1==$1;print} ==>';echo $var | awk '{$1==$1;print}'
Die Ausgabe mit„0“ (Zahl Null):
[root@host ~]# sh /tmp/te.sh 0
o/p of $1=$1 ==>
o/p of {$1=$1;print} ==>0
o/p of $1==$1 ==>0
o/p of {$1==$1;print} ==>0
[root@GORJALA ~]#
Die Ausgabe mit"1" (Nummer eins):
[root@host ~]# sh /tmp/te.sh 1
o/p of $1=$1 ==>1
o/p of {$1=$1;print} ==>1
o/p of $1==$1 ==>1
o/p of {$1==$1;print} ==>1
[root@host ~]#
Warum gibt es einen Unterschied, wenn ich var=0; echo $var | awk '$1=$1'
und verwende var=1; echo $var | awk '$1=$1'
? Alle Zahlen außer funktionieren einwandfrei 0
.
Versionen:
- GNU Bash, Version 4.2.46
- GNU Awk 4.0.2
- coreutils-8.22-24.el7.x86_64
Antwort1
Von demDas GNU Awk-Benutzerhandbuch:
Eine Zuweisung ist ein Ausdruck und hat daher einen Wert – denselben Wert, der zugewiesen wird. Daher ist „z = 1“ ein Ausdruck mit dem Wert eins.
Also
echo 0 | awk '$1=$1'
Das Muster wird als 0 (FALSCH) ausgewertet.echo 1 | awk '$1=$1'
Das Muster wird als 1 (WAHR) ausgewertet und die Standardaktionprint
wird ausgeführt
Antwort2
Ich glaube nicht, dass es eine Frage des numerischen Wertes ist: Das wird (zumindest hier) durch die Standardkonvertierungen berücksichtigt.
Der OP zeigt vier verschiedene Awk-Codes, alles Variationen von: Muster { Aktion }
(a) 1 $ = 1 $
Dadurch wird $1 sich selbst zugewiesen. Es handelt sich nicht um einen Booleschen Test, sondern um einen No-Op (effektiv) und es wird der Wert von $1 zurückgegeben. Wenn $1 eine 0 ist, lautet das MusterFALSCHund die StandardeinstellungDruckvorgang wird komplett übersprungenWenn $1 ungleich Null ist,Eingabe wird gedruckt.
(b) { $1 = $1; drucken; }
Dadurch wird $1 sich selbst zugewiesen, ebenfalls ein No-Op. Wenn kein Muster vorliegt, wird die Aktion ausgeführt und die Eingabe istimmer gedruckt.
(c) $1 == $1
Das ist ein Boolescher Ausdruck, derimmer wahr. 0 ist 0 und 1 ist 1 (und Erdferkel ist Erdferkel). In Abwesenheit einer Aktion ist die Eingabeimmer gedruckt.
(d) { $1 == $1; drucken; }
Es gibt kein Muster. Der Vergleich ergibt einen wahren Boolean-Wert, der verworfen wird. Die Eingabe istimmer gedruckt.
Antwort3
Die vorhandenen Antworten können nicht erklären, warum
echo 0 | awk '$0="0"'
echo 0 | awk '$0=substr($0,1)'
echo 0 | awk '$0=$0""'
wird alles gedruckt 0
, aber
echo 0 | awk '$0'
echo 000 | awk '$0'
druckt nichts, obwohl der Musterausdruck in allen Fällen als ausgewertet wird 0
.
Wie kommt es, dass 0
es in einem Fall wahr und im anderen falsch ist?
Das liegt daran, dass die "Feldvariablen" (das Ergebnis des $
Operators) alsbesonderer Fallund werden (sofern möglich) automatisch umgewandelt innumerische Zeichenfolgen, das, wenn es numerisch gleich ist 0
, als falsch betrachtet wird, wenn es in einem booleschen Kontext verwendet wird:
Ein Stringwert gilt alsnumerische Zeichenfolgewenn es von einem der folgenden stammt:
Feldvariablen
Eingabe aus der
getline()
Funktion
FILENAME
ARGV
Array-Elemente
ENVIRON
Array-Elemente
split()
Von der Funktion erstellte Array-ElementeEine Befehlszeilenvariablenzuweisung
Variablenzuweisung von einer anderen numerischen Zeichenfolgenvariable
und [wenn es wie eine Zahl aussieht, lesen Sie die gesamte BeschreibungHier]
Bitte lesen Sie auch dieRATIONALE
für die Gründe, warum das Konzept numerischer Zeichenfolgen und diese Sondergehäuse erforderlich waren, insbesondere der Teil über einen Vergleich, der beispielsweise „ echo 0 000 | awk '$1==$2'
wahr, aber nicht“ ist echo 0 | awk '$1=="000"'
.
$0
Beachten Sie als weitere Eigenart, dass (der aktuelle Eingabedatensatz) zumindest in einigen Implementierungen seine magische Eigenschaft als „numerische Zeichenfolge“ verliert, wenn eine Zuweisung zu einem Unterfeld eine Neuberechnung verursacht:
$ echo 0 | gawk '{$1=0} $0'
0
Dies scheint nicht durch den Standard abgedeckt zu sein, obwohl es dem Verhalten von nawk/bwk entspricht, auf dem das Standard-awk basiert (aber nicht dem von mawk).
Außerdem dürfen awk-Implementierungen und in der Eingabe als entsprechende Gleitkommazahlen erkennen, obwohl die Unterstützung hierfür lückenhaft und inkonsistent ist. Sie könnten trotzdem von zB. erwischt werden NAN
.INF
INFINITY
echo But his daughter named Nan | awk '$NF'
druckt nichts in FreeBSDs awk (bwk, original-awk).
Antwort4
Denn $0 ist dergesamter Datensatz(komplette Zeile), $1, $2, sindFelder(normalerweise durch Leerzeichen getrennt) darin.