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:

  1. vain tietyn koneen tarttumiseen,
  2. kaikkien tartuntaan koneet

Kommentit

  • tarttuu kaikkiin koneisiin – mikä on kaikkien koneiden nimeämiskäytäntö? onko heidän nimissään yhteinen etuliite?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. niin edelleen!
  • ainoa syötteeni tälle koko kyselylle pitäisi olla ' abax55 ', levätä kaikki on tehtävä kuorella
  • Kysymyksesi on edelleen epäselvä ja täytyy se on grep? Jos jyrsiminen on yhdessä tapauksessa helppoa, tulosta tuo teksti ennen tulosta
  • grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -" tai awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

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

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *