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:
- para fazer o grep apenas em uma máquina particular,
- para fazer o grep de todos máquinas
Comentários
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 emawk
). - 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"; }
rep -o "hl:load_avg=38.980000" machines | xargs -L 1 echo "abax55@lp55cs008 -"
ou awkawk 'match($0,/hl:load_avg=38.980000/) { print "abax55@lp55cs008 - " substr($0,RSTART,RLENGTH) }' machines