我在 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