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.2084839
imprimir 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;
exit
en el comando awk sale después de imprimir la primera coincidencia.
O
Simplemente canalice la salida del for
comando al siguiente comando awk,
for .... | awk -F'[(/]' '{print $2;exit}'
Respuesta2
No necesita el for
bucle: una sola llamada grep
generará 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 awk
ni grep
ninguno 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.sh
y dándole una cadena y un nombre de archivo como argumento. Estos luego se convierten $1
en y $2
respectivamente. Presumiblemente, lo está ejecutando con algo similar a
foo.sh SearchPattern LogFileName
En cualquier caso, el for
bucle es i) completamente inútil ya que no estás utilizando la i
variable creada por el for i in ...
bucle. ii) muy mal ya que eso hará i
tomar 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 awk
nota que "$1"
no está entre comillas simples. Esto hace que bash lo expanda a lo que sea que esté actualmente contenido $1
antes de pasarlo a awk
.