Grep 3 Großbuchstaben und Ziffern in zwei Variablen

Grep 3 Großbuchstaben und Ziffern in zwei Variablen

Ich habe ein Skript erstellt, das eine for loopSchleife 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.5Min eine Variable namens SIZEund die SPIin eine andere Variable namens umleiten PROJECT. Da es sich natürlich um eine Schleife handelt, ändert sich die Variable SIZEund 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 awkImplementierungen wie die nawkoder Solaris mawkoder ältere Versionen von die Intervalloperatoren für reguläre Ausdrücke / gawknicht 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}gawkPOSIXLY_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 grepoder 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.

verwandte Informationen