
Ich habe ein Skript erstellt, das eine for loop
Schleife durch ein IBM-Skript verwendet, um die Größe von Verzeichnissen zu ermitteln. Das Skript gibt dann die Verzeichnisgröße und den Pfad zu einem Slack-Kanal aus, damit diese einfach angezeigt werden können. Das Programm funktioniert, aber die Ausgabe des IBM-Skripts ist groß und muss formatiert werden, damit sie in Slack leicht lesbar ist. Ich muss also zwei Informationen sammeln, die in zwei separate Variablen weitergeleitet werden, wobei die Variablen zum Erstellen der Slack-Nachricht verwendet werden. Mein Skript sieht folgendermaßen aus:
SIZE () {
for dir in /path/to/dir/*
do
cd /usr/lpp/mmfs/samples/ilm/
SLACKMESSAGE=$(./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h)
SLACK
done
}
Dasselbe /path/to/dir/*
gilt für das übergeordnete Verzeichnis. Das IBM-Skript ./mmpolicy-du.sample "$dir" -t /mmfs1/.policytmp -g /mmfs1/.policytmp/ -N all -v -h
durchläuft alle untergeordneten Verzeichnisse (eine Ebene tief) und ermittelt deren Größe. Die Ausgabe sieht folgendermaßen aus:
[I] 2018-05-31@16:32:55.798 Policy execution. 0 files dispatched.
[I] 2018-05-31@16:32:55.804 Policy execution. 0 files dispatched.
File system scan complete.
534.5M total
mmapplypolicy du for /path/to/directory/SPI/ complete at Thu May 31 17:32:55 2018
Das ist nicht die sauberste Ausgabe, daher möchte ich die Verzeichnisgröße im obigen Beispielfall 534.5M
in eine Variable namens SIZE
und die SPI
in eine andere Variable namens umleiten PROJECT
. Da es sich natürlich um eine Schleife handelt, ändert sich die Variable SIZE
und in jedem Verzeichnis im obigen Beispiel von . Die Slack-Funktion, die in meiner obigen Funktion aufgerufen wird, verwendet diese beiden Variablen. Ich habe Schwierigkeiten herauszufinden, wie ich diese beiden in Variablen bekomme. Hat jemand eine Lösung? Danke!PROJECT
/path/to/dir/
Antwort1
So erledigen Sie es in einem Rutsch:
eval "$(yourscript | awk -v q=\' '
$1 ~ /^[[:digit:]]+(\.[[:digit:]]+)?[MGT]$/ {
print "SIZE=" $1
}
match($0, /[[:upper:]]{3}/) {
print "PROJECT="q substr($0, RSTART, RLENGTH) q
}')"
Beachten Sie, dass einige awk
Implementierungen wie die nawk
oder Solaris mawk
oder ältere Versionen von die Intervalloperatoren für reguläre Ausdrücke / gawk
nicht unterstützen (bei älteren (und nicht antiken) Versionen von können Sie es jedoch mit in der Umgebung ausführen, damit es sie unterstützt), obwohl dies seit über 25 Jahren Standard ist. Bei diesen müssten Sie durch ersetzen .{x,y}
{x}
gawk
POSIXLY_CORRECT=anything
[[:upper:]]{3}
[[:upper:]][[:upper:]][[:upper:]]
Antwort2
Ich bezweifle sehr, dass dies das ist, was Sie brauchen, aber dies beantwortet Ihre aktuelle Frage wörtlich.
Erster Teil (GNU grep
oder kompatibel vorausgesetzt):
project="$(yourscript|grep -oE '[[:upper:]]{3}')"
Zweiter Teil:
size="$(yourscript|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"
In Kombination ist es einfacher, das Skript einmal auszuführen, die Ausgabe zu speichern und die gespeicherte Ausgabe mit grep und zuweisen:
output="$(script)"
size="$(printf '%s\n' "$output"|grep -oE '[[:digit:]]+(\.[[:digit:]]+)?[MGT]')"
project="$(printf '%s\n' "$output"|grep -oE '[[:upper:]]{3}')"
Einige Erklärungen
grep -o
– gibt nur das greppte Objekt zurück, nicht die ganze Zeile
-E
– Erweiterter regulärer Ausdruck
[[:upper:]]
– passt nur zu Großbuchstaben ([AZ], aber unabhängig vom Gebietsschema)
{3}
– begrenzt die Übereinstimmung auf genau 3 aufeinanderfolgende Zeichen.
[[:digit:]]
– passt zu Ziffern ([0-9], auch hier ohne Berücksichtigung des Gebietsschemas)
+
– passt 1 oder mehr Mal
\.
– passt zu einem Punkt
(...)?
– passt 0 oder 1 Mal – dies stellt sicher, dass auch Zahlen ohne Dezimalpunkt erfasst werden können
[xy]
– passt genau zu einem der Elemente x oder y.