Bash-Skript zum Lesen des ersten Arguments als Eingabe und zeilenweisen Suchen nach Variablen in einer anderen Datei

Bash-Skript zum Lesen des ersten Arguments als Eingabe und zeilenweisen Suchen nach Variablen in einer anderen Datei

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 $2der Name einer lesbaren Datei ist, weil

  • wenn $2es sich um eine andere als eine lesbare Datei handelt, erhalten Sie eine Fehlermeldung vonawk
  • Wenn $2es leer ist oder fehlt, awkwird 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 ~ thetazu ändern $8 == theta.
  • Variablen in awkwerden auf leer initialisiert. Dies wird in mathematischen Kontexten als 0 behandelt und daher beim ersten Ausführen auf 1 found++gesetzt . Ich habe absichtlich statt dessen gesagt, wenn mehrere Zeilen dem Theta-Wert entsprechen, wird auf den Wert gesetztfoundfound++found = 1foundNummersolcher Zeilen. Dies scheint ein Fehlerzustand zu sein. Wenn Sie darüber besorgt sind, können Sie den ENDBlock so ändern, dass ein Fehler gemeldet wird, wenn der foundWert 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 printAnweisung natürlich aus dem ENDBlock löschen und das Skript nur awkden Beendigungsstatus testen und eine eigene Fehlermeldung ausgeben lassen. Dies sollten Sie auch tun, wenn Sie die Ausgabe von awk(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 die exitAnweisung aus dem ENDBlock 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 grepjedenfalls ein GNU bereitgestellt. Wenn es nach mir ginge, würde ich das allerdings weglassen echooder zumindest tun...

! echo 'Not available.' >&2

...stattdessen.

verwandte Informationen