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하위 쉘을 통해 패턴을 제공하는 것은 어떻습니까 ? 예:

grep -f <(printf "%s\n" "${ptrn[@]}") FILE...

답변2

두 가지 옵션:

  • 표준 준수 방식: 패턴을 개행으로 결합하고 단일 인수로 제공합니다.

    grep -e "$(printf "%s\n" "${ptrn[@]}")" ...
    

    (이 기능은 다음에 의해 지정됩니다.POSIX 표준: "패턴_목록의 값은 <newline> 문자로 구분된 하나 이상의 패턴으로 구성됩니다 ...")

  • 비표준이지만 여전히 안전한 방법: bash와 같은 배열이 포함된 셸을 사용하는 경우 다음에 대한 인수 배열을 만듭니다 grep.

    args=()
    for p in "${ptrn[@]}"
    do
       args+=(-e "$p")
    done
    grep "${args[@]}" ...
    

    이는 필드 분할 및 글로빙으로부터 안전하며 일반적으로 다음과 같습니다.변수에서 명령줄을 작성하는 방법.

답변3

배열 요소로 저장된 패턴/단어에 공백이나 이스케이프되지 않은 셸 특수 문자가 없는 것이 보장되는 경우 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

또는 이스케이프되지 않은 셸 특수 문자가 포함될 수 있는 경우 |(또는) (모든 공간에서도 분할되지만 실패하지는 않습니다.) 다음과 같이 사용하세요.

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

관련 정보