Eu tenho uma sequência de padrões de pesquisa armazenados em um array bash ( ptrn
), que desejo passar para um grep
comando. Como eu posso fazer isso?
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
Responder1
Que tal fornecer os padrões grep
através de um sub-shell, por exemplo:
grep -f <(printf "%s\n" "${ptrn[@]}") FILE...
Responder2
Duas opções:
Maneira compatível com os padrões: junte os padrões com nova linha e forneça-os como argumento único:
grep -e "$(printf "%s\n" "${ptrn[@]}")" ...
(Este recurso é especificado poro padrão POSIX: "Olista_padrãoO valor de deve consistir em um ou mais padrões separados por caracteres <nova linha> ...")
Maneira não padrão, mas ainda segura: ao usar um shell com matrizes, como, por exemplo, bash, crie uma matriz de argumentos para
grep
:args=() for p in "${ptrn[@]}" do args+=(-e "$p") done grep "${args[@]}" ...
Isso é protegido contra divisão de campo e globulação e, em geral, écomo as linhas de comando devem ser construídas a partir de variáveis.
Responder3
Se for garantido que seus padrões/palavras armazenados como elementos da matriz não contenham espaços ou caracteres especiais de shell sem escape, você poderá usar a bash
expansão do parâmetro para passar os elementos da matriz grep
como padrões individuais separados, -e FN -e DS ...
por exemplo:
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
Ou se eles contiverem caracteres especiais de shell sem escape, você poderá criar expressões regulares em torno de |
(ou) (dividindo em todos os espaços também, mas não falhando) e use-o com 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
Ou para preservar espaços exatos dentro de cada padrão de expressão regular, passando cada elemento da matriz como um token individual e construindo uma expressão regular estendida deles usando o |
(lógico ou), você pode fazer algo assim:
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