Imprima apenas a primeira correspondência uma vez

Imprima apenas a primeira correspondência uma vez

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.2084839imprimir 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;

exitno comando awk sai após imprimir a primeira correspondência.

OU

Basta canalizar a saída do forcomando para o comando awk abaixo,

for .... | awk -F'[(/]' '{print $2;exit}'

Responder2

Você não precisa do forloop - uma única chamada grepproduzirá 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, greppois 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.she fornecendo uma string e um nome de arquivo como argumento. Estes então se tornam $1e $2respectivamente. Presumivelmente, você está executando algo semelhante a

foo.sh SearchPattern LogFileName

De qualquer forma, o forloop é i) completamente inútil, pois você não está usando a ivariável criada pelo for i in ...loop. ii) muito errado, pois isso fará com que io 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 awkobservaçã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 $1antes de ser passado para awk.

informação relacionada