Warum verhält sich awk bei 1 $ anders, wenn der Wert 0 (Zahl Null) ist?

Warum verhält sich awk bei 1 $ anders, wenn der Wert 0 (Zahl Null) ist?

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 Standardaktion printwird 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 0es 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:

  1. Feldvariablen

  2. Eingabe aus der getline()Funktion

  3. FILENAME

  4. ARGVArray-Elemente

  5. ENVIRONArray-Elemente

  6. split()Von der Funktion erstellte Array-Elemente

  7. Eine Befehlszeilenvariablenzuweisung

  8. Variablenzuweisung von einer anderen numerischen Zeichenfolgenvariable

und [wenn es wie eine Zahl aussieht, lesen Sie die gesamte BeschreibungHier]

Bitte lesen Sie auch dieRATIONALEfü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"'.


$0Beachten 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.INFINFINITY

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.

verwandte Informationen