我在 bash 数组 ( ) 中存储了一系列搜索模式ptrn
,我想将其传递给grep
命令。我该怎么做?
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
答案1
grep
如何通过子 shell提供模式,例如:
grep -f <(printf "%s\n" "${ptrn[@]}") FILE...
答案2
两个选项:
符合标准的方式:用换行符连接模式并将其作为单个参数提供:
grep -e "$(printf "%s\n" "${ptrn[@]}")" ...
(此功能由POSIX 标准: “这模式列表的值应由一个或多个以 <newline> 字符分隔的模式组成...”)
非标准但仍然安全的方式:当使用带有数组的 shell 时,例如 bash,构建一个参数数组以
grep
:args=() for p in "${ptrn[@]}" do args+=(-e "$p") done grep "${args[@]}" ...
这对于字段分割和通配符来说是安全的,并且一般来说如何根据变量构建命令行。
答案3
如果保证作为数组元素存储的模式/单词中不包含空格或非转义的 shell 特殊字符,那么您可以使用的bash
参数扩展将数组元素传递给grep
单独的单个模式,例如-e FN -e DS ...
:
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
或者,如果它们可能包含非转义的 shell 特殊字符,则可以围绕|
(或者)(在所有空间上分裂,但不会失败)并将其与以下内容一起使用:
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
或者保留每个正则表达式模式内的精确空格,将每个数组元素作为单独的标记传递,并使用|
(构建它们的扩展正则表达式逻辑或),你可以这样做:
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