Imprime solo la primera coincidencia una vez

Imprime solo la primera coincidencia una vez

Tengo un fragmento de código que estoy usando para analizar un archivo de registro e imprimir la información que necesito.

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk '/\([a-zA-Z0-9.]+/ {print $7}' 
 done;

El problema es que cuando ingreso datos, muestra la respuesta varias veces:

(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)

¿Hay alguna manera de recortar esto para que solo pueda mostrar la primera serie de datos una vez? Sólo necesito 1.3.51.0.1.1.10.10.30.48.2084865.2084839imprimir una vez.

Intenté cambiarlo a esto también, pero a Bash no le gusta:

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk '/\([a-zA-Z0-9.]+/' |
        awk -F'[(/]' ' {print $2, exit}'
done;

Luego probé esto:

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk -F'[(/]' '/\([a-zA-Z0-9.]+/ {print $2, exit }'
done;

Respuesta1

Prueba esto,

for i in $(cat ~/jlog/"$2"); do
        grep "$1" ~/jlog/"$2" |
        awk '/\([a-zA-Z0-9.]+/ {print $7; exit}' 
done;

exiten el comando awk sale después de imprimir la primera coincidencia.

O

Simplemente canalice la salida del forcomando al siguiente comando awk,

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

Respuesta2

No necesita el forbucle: una sola llamada grepgenerará todas las líneas coincidentes del archivo, por lo que simplemente repetirá la misma operación una y otra vez tantas veces como líneas haya en el archivo.

Técnicamente, no necesitas ambos awkni grepninguno de los dos, ya que ambos pueden realizar coincidencias textuales. Si desea una respuesta más específica, publique un extracto del archivo de registro y un ejemplo del resultado que desea.

Respuesta3

No has explicado lo que estás haciendo realmente, así que haré un par de suposiciones. Supongo que está ejecutando un script llamado foo.shy dándole una cadena y un nombre de archivo como argumento. Estos luego se convierten $1en y $2respectivamente. Presumiblemente, lo está ejecutando con algo similar a

foo.sh SearchPattern LogFileName

En cualquier caso, el forbucle es i) completamente inútil ya que no estás utilizando la ivariable creada por el for i in ...bucle. ii) muy mal ya que eso hará itomar el valor de cada unopalabray no toda la línea, que es en lo que probablemente estabas pensando iii) la causa de todos tus problemas. Obtienes los mismos resultados varias veces porque estás ejecutando exactamente el mismo comando varias veces. Obtendrá un resultado por cada línea de su archivo.

De todos modos, lo que quieras se puede hacer con algo tan simple como

grep "$1" ~/jlog/"$2" | awk '/\([a-zA-Z0-9.]+/ {print $7}' 

O, más simple:

awk '/'"$1"'/\([a-zA-Z0-9.]+/ {print $7}' ~/jlog/"$2"

La awknota que "$1"no está entre comillas simples. Esto hace que bash lo expanda a lo que sea que esté actualmente contenido $1antes de pasarlo a awk.

información relacionada