Tenho os seguintes detalhes da consulta processada:

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 deseja grep apenas hl:load_avg=38.980000 com prefixo abax55@lp55cs008 que significa que a saída deve ser semelhante a:

abax55@lp55cs008 - hl:load_avg=38.980000 

…. isso é apenas para uma máquina chamada cs008. e o número total de máquinas seria 100+.

Por favor, sugira 2 opções:

  1. para fazer o grep apenas em uma máquina particular,
  2. para fazer o grep de todos máquinas

Comentários

  • grepping em todas as máquinas – qual é a convenção de nomenclatura para todas as máquinas? eles têm um prefixo comum em seus nomes?
  • abax55 @ lp55cs001 abax55 @ lp55cs002 abax55 @ lp55cs003 abax55 @ lp55cs004 …. assim por diante!
  • minha única entrada para este querry inteiro deve ser ' abax55 ', resto tudo tem que ser feito pelo shell
  • Sua pergunta ainda não está clara e deve seja grep? Se, em um caso, o grep for fácil, imprima esse texto antes do resultado
  • Usando 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

Resposta

Awk solução:

1) para realizar o grep apenas em uma máquina específica:

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

O resultado:

abax55@lp55cs008 - hl:load_avg=38.980000 

2) para realizar grep em todas as máquinas:

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

Comentários

  • é possível executar o comando inteiro em uma única linha?
  • @Nayak, elabore sua pergunta, parece vago
  • é possível ' awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} awk -vm = " cs008 " ' / abax55 @ lp55cs [0-9] / & & $ 1 ~ m {m_name = $ 1} ' em uma única linha?
  • sim. isso pode ser executado em uma única linha. Substitua as novas linhas no script awk citado por ; caracteres. (uma ou ambas as novas linhas e ; podem ser usados para separar instruções em awk).
  • solução muito simples e o tempo de execução está baixo …. muito obrigado

Resposta

Para teste, inseri o mesmo conteúdo no arquivo várias vezes, alterando os nomes de host no arquivo

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 

saída

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

Comentários

  • @Nayak Você pode votar na resposta

Resposta

Eu não usaria grep Eu usaria 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"} 

Provavelmente posso refiná-lo se você “puder fornecer um formato de registro mais específico. Mas você pode analisar a estrofe inteira em um bloco com bastante facilidade, porque cada novo “bloco” não tem espaço em branco no início (é ainda mais fácil se houver um delimitador claro entre os registros, como uma linha em branco, mas sem ver sua saída, não sei o que seria).

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

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *