Ich habe die folgenden Details aus der verarbeiteten Abfrage:

queuename qtype resv/used/tot. np_load arch states --------------------------------------------------------------------------------- abax55@lp55cs008 BP 0/36/36 1.08 lx-amd64 gf:app_monitor=1 gf:app_abaqus=1 gf:app_abaqusfgs=1 gf:app_actran=1 hl:load_avg=38.980000 hl:load_short=38.550000 hl:load_medium=38.980000 hl:load_long=39.030000 

I. Ich möchte nur hl:load_avg=38.980000 mit dem Präfix abax55@lp55cs008 erfassen. Dies bedeutet, dass die Ausgabe folgendermaßen aussehen sollte:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. dies ist nur für einen Computer mit dem Namen cs008. und die Gesamtzahl der Maschinen wäre 100+.

Bitte schlagen Sie zwei Optionen vor:

  1. , um nur eine bestimmte Maschine zu erfassen,
  2. um alle zu erfassen Maschinen

Kommentare

  • alle Maschinen – Wie lautet die Namenskonvention für alle Maschinen? Haben sie ein gemeinsames Präfix in ihren Namen?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. so weiter!
  • meine einzige Eingabe für diesen gesamten Abfrage sollte ‚ abax55 ‚ sein, alles muss per Shell erledigt werden
  • Ihre Frage ist noch unklar und muss es ist grep? Wenn das Greppen in einem Fall einfach ist, drucken Sie diesen Text vor dem Ergebnis aus.
  • Verwenden Sie grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -" oder awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

Antwort

Awk Lösung:

1) um nur eine bestimmte Maschine zu erfassen:

awk -v m="cs008" "/abax55@lp55cs[0-9]/ && $1 ~ m{ m_name=$1 } m_name && /hl:load_avg=/{ print m_name" - "$1; exit }" file 

Die Ausgabe:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) zum Erfassen aller Maschinen:

awk "/abax55@lp55cs[0-9]/{ m_name=$1 } m_name && /hl:load_avg=/{ print m_name" - "$1; m_name=0 }" file 

Kommentare

  • Ist es möglich, den gesamten Befehl in einer einzigen Zeile auszuführen?
  • @Nayak, arbeiten Sie Ihre Frage aus, es klingt vage
  • ist es möglich, ‚ awk -vm = “ cs008 “ ‚ / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} awk -vm = “ cs008 “ ‚ / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} ‚ in einer einzelnen Zeile?
  • ja. Dies kann alles in einer Zeile ausgeführt werden. Ersetzen Sie die Zeilenumbrüche im zitierten awk-Skript durch ; -Zeichen. (Eine oder beide Zeilenumbrüche und ; können verwendet werden, um Anweisungen in awk zu trennen.)
  • sehr einfache Lösung und die Laufzeit ist niedrig …. vielen Dank

Antwort

Zum Testen habe ich den gleichen Inhalt eingefügt in Datei mehrmals durch Ändern der Hostnamen in Datei

input file queuename qtype resv/used/tot. np_load arch states --------------------------------------------------------------------------------- abax55@lp55cs008 BP 0/36/36 1.08 lx-amd64 gf:app_monitor=1 gf:app_abaqus=1 gf:app_abaqusfgs=1 gf:app_actran=1 hl:load_avg=38.980000 hl:load_short=38.550000 hl:load_medium=38.980000 hl:load_long=39.030000 queuename qtype resv/used/tot. np_load arch states --------------------------------------------------------------------------------- abax55@lp55cs009 BP 0/36/36 1.08 lx-amd64 gf:app_monitor=1 gf:app_abaqus=1 gf:app_abaqusfgs=1 gf:app_actran=1 hl:load_avg=38.980000 hl:load_short=38.550000 hl:load_medium=38.980000 hl:load_long=39.030000 queuename qtype resv/used/tot. np_load arch states --------------------------------------------------------------------------------- abax55@lp55cs007 BP 0/36/36 1.08 lx-amd64 gf:app_monitor=1 gf:app_abaqus=1 gf:app_abaqusfgs=1 gf:app_actran=1 hl:load_avg=38.980000 hl:load_short=38.550000 hl:load_medium=38.980000 hl:load_long=39.030000 

Befehl

 for i in `sed -n "/abax55@lp55cs/p" file.txt |awk "{print $1}"`; do sed -n "/$i/,+5p" file.txt | awk "{print $1}" | sed -n -e "1p" -e "$p" | perl -pne "s/\n/-/"| sed "s/-$/\n/g"; done 

Ausgabe

abax55@lp55cs008-hl:load_avg=38.980000 abax55@lp55cs009-hl:load_avg=38.980000 abax55@lp55cs007-hl:load_avg=38.980000 

Kommentare

  • @Nayak Können Sie für eine Antwort stimmen

Antwort

Ich würde grep Ich würde :

#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my %values = do { local $/; <> } =~ m/(\w+\@\w+).*?hl:load_avg=([\d\.]+)/gms; print Dumper \%values; print $values{"abax55@lp55cs008"} 

Ich kann es wahrscheinlich verfeinern, wenn Sie ein spezifischeres Aufzeichnungsformat angeben können. Sie können die gesamte Zeilengruppe jedoch leicht genug in einen Block zerlegen, da jeder neue „Block“ zu Beginn kein Leerzeichen enthält (es ist sogar noch einfacher, wenn zwischen den Datensätzen ein klares Trennzeichen vorhanden ist, z. B. eine Leerzeile, jedoch ohne zu sehen Ihre Ausgabe kann ich nicht sagen, was das wäre).

#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my $current_host = ""; my %values; #<> reads stdin or files specified on command line. #if that doesn"t work for you, you can "open" a specific file, or #use qx() or backticks to run a a command. while ( <> ) { #match a regex and capture the result if it"s valid. if ( m/^(\w+\@\w+)/ ) { $current_host = $1 }; #lines that start with whitespace are the values. if ( m/^\s+(\w+:\w+)=([\d\.]+)/ ) { #$1 and $2 are captured via the brackets $values{$current_host}{$1} = $2; } } #for debug: print Dumper \%values; #to print a specific key: my $target_key = "hl:load_avg"; foreach my $host ( sort keys %values ) { print "$host - $target_key=",$values{$host}{$target_key},"\n"; } 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.