Tengo una secuencia de patrones de búsqueda almacenados en una matriz bash ( ptrn
), que quiero pasar a un grep
comando. ¿Cómo puedo hacerlo?
ptrn=("FN" "DS")
for fl in "$@"; do # loop through number of files
if [[ -f "$fl" ]]; then
printf '\n%s%s%s\n\n' "$mgn" "==> $flnm <==" "$rst"
grep --color "$ptrn" "$flnm"
fi
done
Respuesta1
¿Qué tal si damos los patrones a grep
través de un subnivel, por ejemplo:
grep -f <(printf "%s\n" "${ptrn[@]}") FILE...
Respuesta2
Dos opciones:
Manera compatible con los estándares: una los patrones con una nueva línea y proporciónelos como un solo argumento:
grep -e "$(printf "%s\n" "${ptrn[@]}")" ...
(Esta característica está especificada porel estándar POSIX: "Ellista_patronesEl valor de consistirá en uno o más patrones separados por caracteres <nueva línea>...")
Manera no estándar, pero aún segura: cuando use un shell con matrices, como, por ejemplo, bash, cree una matriz de argumentos para
grep
:args=() for p in "${ptrn[@]}" do args+=(-e "$p") done grep "${args[@]}" ...
Esto está a salvo de la división de campos y la globalización y, en general, escómo se deben construir las líneas de comando a partir de variables.
Respuesta3
Si se garantiza que sus patrones/palabras almacenados como elementos de matriz no tendrán espacios ni caracteres especiales de shell sin escape, entonces puede usar bash
la expansión del parámetro 'para pasar los elementos de la matriz grep
como patrones individuales separados, por ejemplo, -e FN -e DS ...
así:
ptrn=("FN" "DS")
# Prepend "-e" to each array element
ptrn2="${ptrn[@]/#/-e }"
# Don't quote "$ptrn2" or it will be passed as a single token and wouldn't work.
grep --color $ptrn2 file
O si pueden contener caracteres especiales de shell sin escape, puede crear expresiones regulares alrededor de |
(o) (dividirse en todos los espacios también pero sin fallar) y usarlo con algo como:
ptrn=("FN" "DS")
# Translate spaces " " single or multiple including spaces between words in a single array element into "|".
ptrn2="$(echo ${ptrn[@]} | tr " " "|")"
# -E enables extended regular expressions ... needed for this to work.
grep --color -E "$ptrn2" file
O para preservar espacios exactos dentro de cada patrón de expresión regular pasando cada elemento de la matriz como un token individual y construyendo una expresión regular extendida de ellos usando |
(lógico o), puedes hacer algo como esto:
ptrn=("FN" "DS")
# Append "|" to each array element.
ptrn2="$(printf '%s|' "${ptrn[@]}")"
# Delete the last character i.e. the extra "|".
ptrn2="${ptrn2::-1}"
# -E enables extended regular expressions ... needed for this to work.
grep --color -E "$ptrn2" file