
Ich habe eine Datei „input.txt“ mit den Variablen A1, A2, A3, θ, θ1 und θ2 – ein Beispiel für input.txt sieht wie folgt aus:
$ cat input1.txt
A1=5.2 A2=4.9 A3=6.1 θ=space θ1=2.5 θ2=1.2
A1=3.1 A2=5.1 A3=3.7 θ=triangle θ1=8.1 θ2=3.9
Ich möchte ein Skript erstellen, das über die Datei input.txt ausgeführt wird. Diese Datei wird als zweites Argument übergeben. Das erste Argument wäre der Wert von θ.
Ich habe ein Skript wie folgt erstellt:
#! /bin/bash
file=input1.txt
if grep -q $1 "$file";
then
awk -F '[= ]+' '{ print $12 }' <$2
else
echo "Not available"
fi
}
Aber wenn ich dieses Skript wie folgt ausführe:
./script space input.txt
(das erste Argument ist der Wert von θ und das zweite Argument ist der Dateiname), die Ausgabe sind alle Werte in Feld 12:
$ ./script1 space input1.txt
1.2
3.9
die Ausgabe sollte nur 1.2 sein. Ich habe gesucht und herausgefunden, dass ich eine Schleife erstellen muss, um die Datei zeilenweise zu lesen, aber ich bekomme es nicht zum Laufen.
Antwort1
Sie können die gesamte Arbeit erledigen in awk
:
#!/bin/sh
file=$2
awk -v theta="$1" -F '[= ]+' '
$0 ~ theta { print $12; found++ }
END { if (!found) { print "Not available"; exit 1 } }' "$file"
Möglicherweise möchten Sie eine Fehlerbehandlung hinzufügen, um zu überprüfen, ob zwei Befehlszeilenargumente vorhanden sind und $2
der Name einer lesbaren Datei ist, weil
- wenn
$2
es sich um eine andere als eine lesbare Datei handelt, erhalten Sie eine Fehlermeldung vonawk
- Wenn
$2
es leer ist oder fehlt,awk
wird stillschweigend von der Standardeingabe gelesen.
(Natürlich kann eines oder beide dieser Verhaltensweisen für Sie in Ordnung sein.)
Anmerkungen:
- Sie erhalten möglicherweise gezieltere Ergebnisse, indem Sie
$0 ~ theta
zu ändern$8 == theta
. - Variablen in
awk
werden auf leer initialisiert. Dies wird in mathematischen Kontexten als 0 behandelt und daher beim ersten Ausführen auf 1found++
gesetzt . Ich habe absichtlich statt dessen gesagt, wenn mehrere Zeilen dem Theta-Wert entsprechen, wird auf den Wert gesetztfound
found++
found = 1
found
Nummersolcher Zeilen. Dies scheint ein Fehlerzustand zu sein. Wenn Sie darüber besorgt sind, können Sie denEND
Block so ändern, dass ein Fehler gemeldet wird, wenn derfound
Wert ungleich 1 ist. - Wenn Ihr Skript bei einem gefundenen Wert eine bestimmte Aktion ausführen soll und bei einem fehlenden Wert etwas anderes, können Sie die
print
Anweisung natürlich aus demEND
Block löschen und das Skript nurawk
den Beendigungsstatus testen und eine eigene Fehlermeldung ausgeben lassen. Dies sollten Sie auch tun, wenn Sie die Ausgabe vonawk
(also den θ2-Wert) erfassen möchten. Wenn Sie hingegen nur eine menschenlesbare Fehlermeldung benötigen und den Beendigungsstatus nicht überprüfen müssen, können Sie dieexit
Anweisung aus demEND
Block löschen.
Antwort2
Versuche dies:
#! /bin/bash
file=input1.txt
if grep -q $1 "$file";
then
grep $1 $2 | awk -F '[= ]+' '{ print $12 }'
else
echo "Not available"
fi
Antwort3
Es scheint, als ließe sich Ihre Logik folgendermaßen zusammenfassen:
grep -om1 "$1" < "$2" ||
echo 'Not available.'
... hat grep
jedenfalls ein GNU bereitgestellt. Wenn es nach mir ginge, würde ich das allerdings weglassen echo
oder zumindest tun...
! echo 'Not available.' >&2
...stattdessen.