Mám následující podrobnosti ze zpracovaného dotazu:

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 chcete grepovat pouze hl:load_avg=38.980000 s předponou abax55@lp55cs008, což znamená, že výstup by měl vypadat takto:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. toto je jen pro jeden stroj s názvem cs008. a celkový počet strojů by byl více než 100.

Navrhněte prosím 2 možnosti:

  1. pro grepování pouze konkrétního stroje,
  2. pro grepování všech stroje

Komentáře

  • grepování všech strojů – jaká je konvence pojmenování pro všechny stroje? mají ve svých jménech společnou předponu?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. tak dále!
  • můj jediný vstup pro celý tento dotaz by měl být ' abax55 ', zbytek musí udělat shell
  • Vaše otázka je stále nejasná a musí je to grep? Pokud je pro jeden případ snadné grepování, vytiskněte tento text před výsledkem
  • pomocí grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -" nebo awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

Odpověď

Awk řešení:

1) pro grepování pouze konkrétního stroje:

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

Výstup:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) pro grepování všech strojů:

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

Komentáře

  • je možné spustit celý příkaz v jednom řádku?
  • @Nayak, rozpracovat otázku, zní to vágní
  • je možné ' awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} ' v jednom řádku?
  • ano. to lze spustit vše na jednom řádku. Nahraďte nové řádky v citovaném skriptu awk znaky ;. (k oddělení výroků v awk lze použít buď nový řádek, nebo ;).
  • velmi jednoduché řešení a doba běhu je nízká …. moc děkuji

odpověď

Pro testování jsem vložil stejný obsah v souboru několikrát změnami názvů hostitelů v souboru

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 

příkaz

 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 

výstup

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

Komentáře

  • @Nayak Můžete hlasovat pro odpověď

Odpověď

Nepoužíval bych grep Použil bych 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"} 

Pravděpodobně to zpřesním, pokud budete moci poskytnout konkrétnější formát záznamu. Můžete však snadno analyzovat celou sloku do bloku, protože každý nový „blok“ nemá na začátku mezery (je to ještě snazší, pokud je mezi záznamy jasný oddělovač, například prázdný řádek, ale bez vidění váš výstup nemohu říci, co by to bylo).

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

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *