Jai les détails suivants de la requête traitée:

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 voulez grep uniquement hl:load_avg=38.980000 avec le préfixe abax55@lp55cs008 ce qui signifie que la sortie doit ressembler à:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. ceci est juste pour une machine nommée cs008. et le nombre total de machines serait plus de 100.

Veuillez suggérer 2 options:

  1. pour grepping seulement une machine particulière,
  2. pour grepping all machines

Commentaires

  • grepping toutes les machines – quelle est la convention de dénomination pour toutes les machines? ont-ils un préfixe commun dans leurs noms?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. ainsi de suite!
  • ma seule entrée pour tout ce querry devrait être ‘ abax55 ‘, reste tout doit être fait par shell
  • Votre question nest toujours pas claire et doit ce soit grep? Si pour un cas le grepping est facile, alors imprimez ce texte avant le résultat
  • En utilisant grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -", ou awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

Réponse

Awk solution:

1) pour grepping uniquement une machine particulière:

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

La sortie:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) pour grepping toutes les machines:

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

Commentaires

  • est-il possible dexécuter la commande entière sur une seule ligne?
  • @Nayak, élaborez votre question, ça sonne vague
  • est-il possible de ‘ awk -vm =  » cs008  » ‘ / abax55 @ lp55cs [0-9] / & & 1 $ ~ m {m_name = $ 1} awk -vm =  » cs008  » ‘ / abax55 @ lp55cs [0-9] / & & 1 $ ~ m {m_name = $ 1} ‘ en une seule ligne?
  • oui. tout cela peut être exécuté sur une seule ligne. Remplacez les nouvelles lignes dans le script awk entre guillemets par des caractères ;. (lune ou lautre ou les deux newline et ; peuvent être utilisées pour séparer les instructions dans awk).
  • solution très simple et le temps dexécution est faible … merci beaucoup

Réponse

Pour les tests, jai inséré le même contenu dans le fichier plusieurs fois en modifiant les noms dhôtes dans le fichier

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 

commande

 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 

sortie

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

Commentaires

  • @Nayak Pouvez-vous voter pour la réponse

Réponse

Je nutiliserais pas grep Jutiliserais 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"} 

Je peux probablement laffiner si vous « êtes en mesure de donner un format denregistrement plus spécifique. Mais vous pouvez analyser la strophe entière en un bloc assez facilement, car chaque nouveau « bloc » na pas despace au début (cest encore plus facile sil y a « un délimiteur clair entre les enregistrements, comme une ligne vide, mais sans voir votre sortie, je ne peux pas dire ce que ce serait).

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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *