Ho i seguenti dettagli dalla query elaborata:
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 voglio solo grep hl:load_avg=38.980000
con prefisso abax55@lp55cs008
che significa che loutput dovrebbe essere simile a:
abax55@lp55cs008 - hl:load_avg=38.980000
…. questo è solo per una macchina denominata cs008
. e il numero totale di macchine sarebbe 100+.
Si prega di suggerire 2 opzioni:
- per grepping solo una macchina particolare,
- per grepping tutto macchine
Commenti
Risposta
Awk
soluzione:
1) per grepping solo una particolare macchina:
awk -v m="cs008" "/abax55@lp55cs[0-9]/ && $1 ~ m{ m_name=$1 } m_name && /hl:load_avg=/{ print m_name" - "$1; exit }" file
Loutput:
abax55@lp55cs008 - hl:load_avg=38.980000
2) per grepping su tutte le macchine:
awk "/abax55@lp55cs[0-9]/{ m_name=$1 } m_name && /hl:load_avg=/{ print m_name" - "$1; m_name=0 }" file
Commenti
- è possibile eseguire lintero comando in una singola riga?
- @Nayak, elabora la tua domanda, suona vago
- è possibile ' 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 una sola riga?
- sì. questo può essere eseguito tutto su una riga. Sostituisci le nuove righe nello script awk citato con
;
caratteri. (uno o entrambi i caratteri newline e;
possono essere utilizzati per separare le istruzioni inawk
). - soluzione molto semplice e il tempo di esecuzione è basso …. grazie mille
Risposta
Per i test ho inserito lo stesso contenuto nel file più volte modificando i nomi host nel file
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
comando
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
output
abax55@lp55cs008-hl:load_avg=38.980000 abax55@lp55cs009-hl:load_avg=38.980000 abax55@lp55cs007-hl:load_avg=38.980000
Commenti
- @Nayak puoi votare per la risposta
Risposta
Non “userei grep
Userei perl
:
#!/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"}
Probabilmente posso perfezionarlo se sei in grado di fornire un formato di registrazione più specifico. Ma puoi analizzare lintera strofa in un blocco abbastanza facilmente, perché ogni nuovo “blocco” non ha spazi allinizio (è ancora più facile se cè “un delimitatore chiaro tra i record, come una riga vuota, ma senza vedere il tuo output non riesco a dire quale sarebbe).
#!/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"; }
rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -"
o awkawk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines