Ik heb de volgende details van de verwerkte zoekopdracht:

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 wil alleen grepen hl:load_avg=38.980000 met voorvoegsel abax55@lp55cs008 dat betekent dat de uitvoer er als volgt uit moet zien:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. dit is slechts voor één machine met de naam cs008. en het totale aantal machines zou 100+ zijn.

Stel 2 opties voor:

  1. voor het grepen van alleen een bepaalde machine,
  2. voor het grepen van alle machines

Opmerkingen

  • grepping all machines – wat is de naamgevingsconventie voor alle machines? hebben ze een gemeenschappelijk voorvoegsel in hun naam?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 … enzovoort!
  • mijn enige invoer voor deze hele vraag zou ‘ abax55 ‘ moeten zijn, rust alles moet met de shell worden gedaan
  • Je vraag is nog steeds onduidelijk en moet het is grep? Als grepping voor één geval eenvoudig is, druk die tekst dan af vóór het resultaat.
  • Gebruik grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -", of awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

Antwoord

Awk oplossing:

1) voor alleen een bepaalde machine grepen:

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

De output:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) voor het grepen van alle machines:

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

Reacties

  • is het mogelijk om het hele commando op één regel uit te voeren?
  • @Nayak, licht je vraag toe, het klinkt vaag
  • is het mogelijk om ‘ awk -vm = ” cs008 ” ‘ / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} awk -vm = ” cs008 ” ‘ / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} ‘ op een enkele regel?
  • ja. dit kan allemaal op één regel worden uitgevoerd. Vervang de nieuwe regels in het awk-script tussen aanhalingstekens door ; -tekens. (een of beide newline en ; kunnen worden gebruikt om statements in awk te scheiden).
  • Zeer eenvoudige oplossing en de runtime is laag …. heel erg bedankt

Antwoord

Voor testen heb ik dezelfde inhoud ingevoegd meerdere keren in bestand door de hostnamen in bestand te wijzigen

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 

commando

 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 

uitvoer

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

Reacties

  • @Nayak Kunt u stemmen voor antwoord

Antwoord

Ik zou grep Ik zou :

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

Ik kan het waarschijnlijk verfijnen als je een meer specifiek recordformaat kunt geven. Maar je kunt de hele strofe gemakkelijk genoeg in een blok parseren, omdat elk nieuw “blok” aan het begin geen witruimte heeft (het is nog gemakkelijker als er een duidelijk scheidingsteken tussen de records staat, zoals een lege regel, maar zonder je output kan ik “niet zeggen wat dat zou zijn).

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *