2010-02-19 5 views
6

¿Es posible hacer un grep con palabras clave almacenadas en la matriz.¿Es posible hacer un grep con las palabras clave almacenadas en la matriz?

Aquí es el posible fragmento de código ... Corrígela

args=("key1" "key2" "key3") 

cat file_name |while read line 
echo $line | grep -q -w ${args[c]} 
done 

Por el momento, puedo buscar una sola palabra clave. Me gustaría buscar todas las palabras clave que se almacenan en args matriz.

Cualquier sugerencia sería muy apreciada.

Gracias, Kiran

+1

Si bien no es realmente una solución, pero cat se utiliza para concatenar archivos, si solo hay un archivo, use la directiva de entrada: mientras lee la línea echo $ line | grep -q -w $ {args [c]} hecho Residuum

+0

Muchas gracias .. Estoy acostumbrado a hacerlo al ver otros ejemplos ... no me di cuenta ... gracias ton – Kiran

Respuesta

5
args=("key1" "key2" "key3") 
pat=$(echo ${args[@]}|tr " " "|") 
grep -Eow "$pat" file 

O con la cáscara

args=("key1" "key2" "key3") 
while read -r line 
do 
    for i in ${args[@]} 
    do 
     case "$line" in 
      *"$i"*) echo "found: $line";; 
     esac 
    done 
done <"file" 
+0

Muchas gracias ... Funcionó. :) – Kiran

0

tal vez algo como esto;

cat file_name |while read line 
for arg in ${args[@]} 
do 
echo $line | grep -q -w $arg} 
done 
done 

¡no probado!

+0

Bueno, necesito buscar tanto las palabras clave al mismo tiempo como $ {args [*]} o con egrep con varias palabras clave. ¿Alguna idea? – Kiran

1

El comando

(IFS="|" ; grep --perl-regexp "${args[*]}") <file_name 

búsquedas la ficha de cada palabra clave en una matriz. Lo hace construyendo la expresión regular word1|word2|word3 que coincide con cualquier palabra de las alternativas dadas (en modo perl).

Si hay una manera de unir elementos de la matriz en una cadena, que delimita con secuencia de caracteres (es decir, \|), que podría hacerse sin expresión regular Perl.

+0

En mi sistema, es singular: '--perl-regexp'. Además, el uso inútil de 'cat'. –

+0

@Dennis, gracias, arreglado. Por cierto, puedo discutir sobre el gato. –

+0

'(IFS ... grep ... file_name)' - no hay necesidad de redirección. ¿Tu 'grep' realmente tiene una" s "en' --perl-regexp'? –

3

Esta es una manera:

args=("key1" "key2" "key3") 
keys=${args[@]/%/\\|}  # result: key1\| key2\| key3\| 
keys=${keys// }   # result: key1\|key2\|key3\| 
grep "${keys}" file_name 

Editar:

Basado en sugerencia de Pavel Shved:

(IFS="|"; keys="${args[*]}"; keys="${keys//|/\\|}"; grep "${keys}" file_name) 

La primera versión como una sola línea:

keys=${args[@]/%/\\|}; keys=${keys// }; grep "${keys}" file_name 

Edit2:

Incluso mejor que la versión utilizando IFS:

printf -v keys "%s\\|" "${args[@]}"; grep "${keys}" file_name 
+0

¿Puedes explicar cómo funciona tu solución? Estoy atascado en comprender el propósito del% en tu patrón args [@] /%/\\ | – Sharad

+0

@Sharad: consulte el Manual de Bash en Expansión de parámetros de shell] (https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion) en el penúltimo párrafo. La asignación en mi ejemplo 'keys = $ {args [@] /%/\\ |}' dice que reemplazar ('/') el final ('%') de cada elemento de la matriz ('args [@]') con ('/') una barra invertida y una tubería ('\\ |'). Por lo tanto, agrega esos caracteres ya que el "final" (un '%' seguido de ningún otro carácter para que coincida) es solo eso, no se eliminan los caracteres durante el "reemplazo" en este caso. –

2

Se puede utilizar un poco de magia de expansión que bash prefijo cada elemento con -e pasa cada elemento del arra y como un patrón separado. Esto puede evitar algunos problemas de precedencia donde sus patrones pueden interactuar mal con el | operador:

$ grep ${args[@]/#/-e } file_name 

La desventaja de esto es que no se puede tener espacios en sus patrones porque eso va a dividir los argumentos a grep. No puede poner comillas alrededor de la expansión anterior, de lo contrario obtendrá "-e pattern" como un argumento único para grep.

Cuestiones relacionadas