Eu tenho um trecho de código que estou usando para analisar um arquivo de log e imprimir as informações necessárias.
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/ {print $7}'
done;
O problema é que quando eu insiro a entrada, ela exibe a resposta várias vezes:
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.280.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.283.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109696.2)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109706.51)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109758.100)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109773.149)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109810.198)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109818.247)
Existe alguma maneira de cortar isso para que a primeira série de dados seja exibida apenas uma vez. Só preciso 1.3.51.0.1.1.10.10.30.48.2084865.2084839
imprimir uma vez.
Tentei mudar para isso também, mas Bash não gostou:
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/' |
awk -F'[(/]' ' {print $2, exit}'
done;
Então tentei isso:
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk -F'[(/]' '/\([a-zA-Z0-9.]+/ {print $2, exit }'
done;
Responder1
Tente isso,
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/ {print $7; exit}'
done;
exit
no comando awk sai após imprimir a primeira correspondência.
OU
Basta canalizar a saída do for
comando para o comando awk abaixo,
for .... | awk -F'[(/]' '{print $2;exit}'
Responder2
Você não precisa do for
loop - uma única chamada grep
produzirá todas as linhas correspondentes do arquivo, então você está apenas repetindo a mesma operação quantas vezes houver linhas no arquivo.
Tecnicamente, você não precisa de ambos awk
, grep
pois ambos podem fazer correspondência textual. Se você quiser uma resposta mais específica, poste uma extração do arquivo de log e um exemplo da saída desejada.
Responder3
Você não explicou o que realmente está fazendo, então farei algumas suposições. Presumo que você esteja executando um script chamado foo.sh
e fornecendo uma string e um nome de arquivo como argumento. Estes então se tornam $1
e $2
respectivamente. Presumivelmente, você está executando algo semelhante a
foo.sh SearchPattern LogFileName
De qualquer forma, o for
loop é i) completamente inútil, pois você não está usando a i
variável criada pelo for i in ...
loop. ii) muito errado, pois isso fará com que i
o valor de cadapalavrae não a linha inteira que você provavelmente estava pensando iii) a causa de todos os seus problemas. Você está obtendo os mesmos resultados várias vezes porque está executando exatamente o mesmo comando várias vezes. Você obterá um resultado para cada linha do seu arquivo.
De qualquer forma, o que você deseja pode ser feito com algo tão simples como
grep "$1" ~/jlog/"$2" | awk '/\([a-zA-Z0-9.]+/ {print $7}'
Ou, mais simples:
awk '/'"$1"'/\([a-zA-Z0-9.]+/ {print $7}' ~/jlog/"$2"
A awk
observação de que the "$1"
não está entre aspas simples. Isso faz com que o bash o expanda para o que quer que esteja atualmente contido $1
antes de ser passado para awk
.