Jag har följande detaljer från bearbetad fråga:

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 vill bara grep hl:load_avg=38.980000 med prefix abax55@lp55cs008 det betyder att utgången ska se ut:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. det här är bara för en maskin som heter cs008. och det totala antalet maskiner skulle vara 100+.

Föreslå två alternativ:

  1. för att bara greppa en viss maskin,
  2. för att greppa alla maskiner

Kommentarer

  • tar emot alla maskiner – vad är namngivningskonventionen för alla maskiner? har de ett gemensamt prefix i sina namn?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. så vidare!
  • min enda ingång för hela denna fråga ska vara ' abax55 ', resten måste allt göras med skal
  • Din fråga är fortfarande oklar och måste det är grep? Om det i ett fall är grepping enkelt, skriv ut texten före resultatet
  • Med grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -", eller awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

Svar

Awk lösning:

1) för att endast ta en viss maskin:

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

Utgången:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) för grepping av alla maskiner:

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

Kommentarer

  • är det möjligt att köra hela kommandot på en enda rad?
  • @Nayak, utarbeta din fråga, det låter vaga
  • är det möjligt att ' awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} ' i en enda rad?
  • ja. detta kan köras allt på en rad. Byt ut de nya raderna i det citerade awk-skriptet med ; tecken. (endera eller båda newline och ; kan användas för att separera uttalanden i awk).
  • väldigt mycket enkel lösning och körtiden är låg …. tack så mycket

Svar

För testning har jag lagt in samma innehåll i fil flera gånger genom att ändra värdnamnen i filen

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 

kommando

 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 

Kommentarer

  • @Nayak Kan du rösta på svar

Svar

Jag skulle inte använda grep Jag skulle använda 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"} 

Jag kan nog förfina det om du kan ge ett mer specifikt inspelningsformat. Men du kan analysera hela strofen i ett block enkelt nog, eftersom varje nytt ”block” inte har något utrymme i början (det är ännu lättare om det finns en tydlig avgränsare mellan posterna, till exempel en tom rad, men utan att se din produktion kan jag inte säga vad det skulle vara.

#!/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"; } 

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *