Tengo los siguientes detalles de la consulta procesada:

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 desea grep solo hl:load_avg=38.980000 con el prefijo abax55@lp55cs008, es decir, la salida debe verse así:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. esto es solo para una máquina llamada cs008. y el número total de máquinas sería 100+.

Sugiera 2 opciones:

  1. para grepping solo una máquina en particular,
  2. para grepping todo máquinas

Comentarios

  • grepping all machines – ¿Cuál es la convención de nomenclatura para todas las máquinas? ¿Tienen un prefijo común en sus nombres?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. ¡así sucesivamente!
  • mi única entrada para toda esta consulta debe ser ' abax55 ', resto, todo debe hacerse por shell
  • Su pregunta aún no está clara y debe ser grep? Si para un caso grepping es fácil, imprima ese texto antes del resultado
  • Usando grep rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -", o awk awk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines

Respuesta

Awk solución:

1) para grepping solo en una máquina en particular:

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

El resultado:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) para grepping en todas las máquinas:

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

Comentarios

  • ¿es posible ejecutar el comando completo en una sola línea?
  • @Nayak, elabora tu pregunta, suena vago
  • ¿es posible ' 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 una sola línea?
  • sí. esto se puede ejecutar todo en una línea. Reemplace las líneas nuevas en el script awk citado con ; caracteres. (ya sea o ambos, la nueva línea y ; se pueden usar para separar declaraciones en awk).
  • una solución muy simple y el tiempo de ejecución es bajo …. muchas gracias

Responder

Para las pruebas, he insertado el mismo contenido en el archivo varias veces cambiando los nombres de host en el archivo

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 

comando

 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 

salida

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

Comentarios

  • @Nayak ¿Puedes votar por la respuesta?

Respuesta

No usaría grep Usaría 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"} 

Probablemente pueda refinarlo si «puede dar un formato de registro más específico. Pero puede analizar toda la estrofa en un bloque con bastante facilidad, porque cada nuevo «bloque» no tiene espacios en blanco al principio (es incluso más fácil si «hay» un delimitador claro entre los registros, como una línea en blanco, pero sin ver su salida no puedo decir cuál sería).

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *