2016-07-25 17 views
0

Ich versuche, die Funktion sqrt aus dem Befehl awk in meinem Skript zu verwenden, aber alles, was zurückgegeben wird, ist 0. Stimmt irgendetwas mit meinem unten stehenden Skript nicht?Versucht, awk sqrt zu verwenden, gibt aber nur 0 zurück

Dies ist mein erstes Mal mit dem Befehl awk, gibt es irgendwelche Fehler, die ich hier nicht verstehe?

+2

Bash-Variablen werden nicht in einfache Anführungszeichen erweitert. Entweder in doppelte Anführungszeichen wechseln oder eine 'awk'-Variable mit' -v '-Option definieren. – karakfa

Antwort

1

Vielleicht können Sie dies versuchen.

echo "enter number" 
read root 
echo "$root" | awk '{print sqrt($0)}' 

Sie müssen awk eine Dateneingabe geben. So können Sie "Echo" pipen. Die BEGIN-Anweisung ist Dinge zu tun, wie zum Beispiel eine Kopfzeile drucken ... usw., bevor awk beginnt, die Eingabe zu lesen.

+0

Das hat mein Problem gelöst, Danke! – eecenja

+0

Nein.Es gibt absolut keine Notwendigkeit für Echo und eine Pipe und wenn Sie dann did ** ** MUSS ** zitieren Sie Ihre Shell-Variablen, es sei denn, Sie haben einen bestimmten Zweck im Sinn, indem Sie sie nicht quoted (z. B. globbing Wildcard-Erweiterung oder Komprimierung von Ketten von weiß Leerzeichen oder eines der anderen Dinge, die die Shell mit nicht-quotierten Variablen als Argumente für einen Befehl ausführt) und alle Vorbehalte vollständig verstehen. –

1

UPDATE: Meine vorgeschlagene Lösung stellt sich als potentiell gefährlich heraus. Eine bessere Lösung finden Sie unter Ed Morton's answer. Ich werde diese Antwort hier als Warnung hinterlassen.

Wegen der einfachen Anführungszeichen wird $root von awk interpretiert, nicht von der Shell. awk behandelt root als nicht initialisierte Variable, deren Wert die leere Zeichenfolge ist, die in einem numerischen Kontext als 0 behandelt wird. $root ist das root 'Feld der aktuellen Zeile - in diesem Fall als $0, das ist die gesamte Zeile. Da es in einem BEGIN Block ist, gibt es keine aktuelle Zeile, also $root ist die leere Zeichenfolge - die wiederum als 0 behandelt wird, wenn sie an sqrt() übergeben wird.

Sie können dies sehen, indem Sie Ihre Befehlszeile ein wenig zu ändern:

$ awk 'BEGIN { print sqrt("") }' 
0 
$ echo 2 | awk '{ print sqrt($root) }' 
1.41421 

HINWEIS: Die oben ist nur zu zeigen, was mit dem ursprünglichen Befehl falsch ist, und wie es von der Shell und von awk interpretiert wird.

Eine Lösung besteht darin, doppelte Anführungszeichen anstelle von einfachen Anführungszeichen zu verwenden. Die Shell erweitert Variablenreferenzen innerhalb von Anführungszeichen:

Sie müssen vorsichtig sein, wenn Sie so etwas tun. Die Interaktion zwischen Zitaten und variabler Expansion in der Shell vs. awk kann kompliziert sein.

UPDATE: In der Tat, müssen Sie extrem vorsichtig sein. Wie Ed Morton in einem Kommentar hervorhebt, kann diese Methode bei einem bösartigen Wert für $x zu willkürlicher Codeausführung führen, was immer ein Risiko für einen Wert darstellt, der von Benutzereingaben gelesen wird. His answer vermeidet dieses Problem.

(Beachten Sie, dass ich den Namen des Shell-Variable $root-$x geändert haben, da sie die Zahl, deren Quadratwurzel ist wollen Sie, nicht die Wurzel selbst.)

+0

'echo 2 | awk '{print sqrt ($ root)}' Ich denke, du meintest stattdessen $ 0. – karakfa

+1

Absolut ** nie ** tun, was in dieser Antwort vorgeschlagen wird. –

+0

@karakfa: Nein, ich meinte was ich geschrieben habe. '$ root' entspricht in diesem Kontext $ 0. –

1
$ echo "enter number" 
enter number 
$ read root 
3 
$ awk -v root="$root" 'BEGIN{ print sqrt(root) }' 
1.73205 

Siehe the comp.unix.shell FAQ für die 2 Korrekte Möglichkeiten, den Wert einer Shell-Variablen an ein awk-Skript zu übergeben.