將多個檔案模式傳遞給 grep

將多個檔案模式傳遞給 grep

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

相關內容