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:

  1. per grepping solo una macchina particolare,
  2. per grepping tutto macchine

Commenti

  • grepping tutte le macchine – qual è la convenzione di denominazione per tutte le macchine? hanno un prefisso comune nei loro nomi?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. così via!
  • il mio unico input per lintera domanda dovrebbe essere ' abax55 ', resto tutto deve essere fatto dalla shell
  • La tua domanda non è ancora chiara e deve essere grep? Se per un caso il grepping è facile, stampa il testo prima del risultato
  • Utilizzando grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -" o awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

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 in awk).
  • 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"; } 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *