여러 모드를 전달하고 싶고 각 모드에 옵션을 적용하는 방법에 대한 grep
많은 솔루션이 있습니다 .-e
다양한 모드가 배열에 저장됩니다 ptrn
. 배열 요소의 공백은 -e
패턴에 개별적으로 전달되지 않기 때문에 잘못 해석될 수 있는지 궁금합니다 .
가능성은
가능성 1
mptrn=$( printf -- ' -e %s' "${ptrn[@]}" )
grep -E "$mptrn" -- "$flnm"
가능성 2
for i in "${!ptrn[@]}"; do
ptrn[$i]="-e ${ptrn[$i]}"
done
grep -E "${ptrn[@]}" -- "$flnm"
가능성 3
eptrn=()
for i in "${!ptrn[@]}"; do
eptrn+=("-e" "${ptrn[$i]}")
done
grep -E "${eptrn[@]}" -- "$flnm"
어떤 솔루션에서든 발생할 수 있는 문제는 무엇입니까?
답변1
이렇게 놔두세요 ptrn=(" a b" " 333 22 1 ")
.
답변 1:
mptrn=$( printf -- ' -e %s' "${ptrn[@]}" )
grep -E "$mptrn" -- "$flnm"
명령의 전체 출력은 에 할당되며 mptrn
, 배열의 요소에 공백 문자가 포함되어 있으면 사용된 형식으로 인해 해당 요소를 구별할 수 없습니다. (선행 및 후행 공백 문자 포함)이 mptrn
포함됩니다 . -e a b -e 333 22 1
실행될 때 grep
인용된 인수는 선행 공백으로 인해 패턴 인수로 해석되며, 이는 "$mptrn"
달성하려는 것이 아닌 지정된 파일에서 항목을 검색합니다. 이 작업과 같은 작업을 수행하려면 다음을 사용할 수 있습니다.IFS
범위.
[ "${IFS+x}" = x ] && OLD_IFS=$IFS
IFS=$(printf '\x7f')
mptrn=$(printf "-e${IFS}%s${IFS}" "${ptrn[@]}")
# note that we don't use quotes
grep -E $mptrn -- "$flnm"
if [ "${OLD_IFS+x}" = x ]; then IFS=$OLD_IFS; else unset IFS; fi
답변 2:
for i in "${!ptrn[@]}"; do
ptrn[$i]="-e ${ptrn[$i]}"
done
grep -E "${ptrn[@]}" -- "$flnm"
이 답변은 검색된 패턴에 선행 공백이 포함된다는 점을 제외하면 원하는 결과에 가깝습니다. 즉, 생성된 명령은 다음과 같습니다.
grep -E "-e a b" "-e 333 22 1 " -- file
공백을 제거하면 문제가 해결됩니다 ptrn[$i]=-e${ptrn[$i]}
.
답변 3:
eptrn=()
for i in "${!ptrn[@]}"; do
eptrn+=("-e" "${ptrn[$i]}")
done
grep -E "${eptrn[@]}" -- "$flnm"
이 대답은 정확합니다. 생성된 grep
명령은 다음과 같습니다.
grep -E -e " a b" -e " 333 22 1 " -- file
답변2
이를 정규식으로 결합합니다. 예를 들어 임의의 패턴과 일치시키려는 경우 정규식 대체 연산자를 |
OR로 사용할 수 있습니다.
먼저 join_by
bash에서 함수를 만듭니다.
join_by () {
local d="$1";
shift;
printf '%s' "$1";
shift;
printf '%s' "${@/#/$d}"
}
perl
이것은 내장 함수의 매우 간단한 복제입니다 join
. 첫 번째 매개변수를 구분 기호로 사용한 다음 해당 구분 기호를 사용하여 추가적인 귀찮은 선행 또는 후행 구분 기호 없이 나머지 모든 매개 변수를 연결합니다.
그런 다음 다음과 같이 사용하십시오.
$ p=(a b c d e)
$ re=$(join_by '|' "${p[@]}")
$ echo $re
a|b|c|d|e
$re를 사용할 수 있습니다 grep -E
(교체하려면 확장 정규식 "ERE"가 필요함).
grep -E "$re" filename
더 복잡한 부울 연산(예 a && b && ! (c || d || e
: )을 수행해야 하는 경우 perl 또는 awk를 사용하세요. bash는 데이터 처리 언어로는 적합하지 않습니다.