Minulla on seuraavat tiedot käsitellystä kyselystä:
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 haluat grepata vain hl:load_avg=38.980000
etuliitteellä abax55@lp55cs008
, mikä tarkoittaa, että lähdön tulisi näyttää tältä:
abax55@lp55cs008 - hl:load_avg=38.980000
…. tämä on vain yksi kone nimeltään cs008
. ja koneiden kokonaismäärä olisi yli 100.
Ehdota 2 vaihtoehtoa:
- vain tietyn koneen tarttumiseen,
- kaikkien tartuntaan koneet
Kommentit
vastaus
Awk
ratkaisu:
1) vain tietyn koneen tarttumiseen:
awk -v m="cs008" "/abax55@lp55cs[0-9]/ && $1 ~ m{ m_name=$1 } m_name && /hl:load_avg=/{ print m_name" - "$1; exit }" file
Tulos:
abax55@lp55cs008 - hl:load_avg=38.980000
2) kaikkien koneiden tarttumiseen:
awk "/abax55@lp55cs[0-9]/{ m_name=$1 } m_name && /hl:load_avg=/{ print m_name" - "$1; m_name=0 }" file
kommentit
- onko mahdollista suorittaa koko komento yhdellä rivillä?
- @Nayak, kehitä kysymyksesi, se kuulostaa epämääräinen
- onko mahdollista ' awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} ' yhdellä rivillä?
- kyllä. tämä voidaan suorittaa kaikki yhdellä rivillä. Korvaa lainatun awk-komentosarjan uudet rivit
;
-merkeillä. (jompaa kumpaa tai molempia newline ja;
voidaan käyttää lauseiden erottamiseenawk
). - hyvin yksinkertainen ratkaisu ja ajonaika on alhainen …. kiitos paljon
vastaus
Testausta varten olen lisännyt samaa sisältöä tiedostossa useita kertoja muuttamalla tiedoston isäntänimiä
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
komento
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
abax55@lp55cs008-hl:load_avg=38.980000 abax55@lp55cs009-hl:load_avg=38.980000 abax55@lp55cs007-hl:load_avg=38.980000
Kommentit
- @Nayak Voitko äänestää vastausta
vastaus
En käytä grep
Käytän 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"}
Voin todennäköisesti tarkentaa sitä, jos pystyt antamaan tarkemman tietuemuodon. Mutta voit jäsentää koko jakson lohkoksi tarpeeksi helposti, koska jokaisella uudella ”lohkolla” ei ole tyhjää tilaa alussa (se on vielä helpompaa, jos tietueiden välillä on selkeä erotin, kuten tyhjä rivi, mutta näkemättä Tuloksestasi en voi kertoa mikä se olisi.
#!/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 -"
tai awkawk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines