awk 또는 grep을 사용하여 그룹 캡처

awk 또는 grep을 사용하여 그룹 캡처

발견된 각 패턴을 반복하고 루프 내에서 다른 캡처 그룹에 액세스하고 싶습니다. 가능 하면 grep또는를 사용하여 awk세 번째 패턴을 학습하지 않도록 계속 사용하고 싶지만 실제로 필요한 경우 하나 더 알아보세요!)

다음과 같이 하십시오:

awk-or-grep -E '(blah(.*)hello=(.*))' sampletext | while read -r l; do 
    echo $0             #1st capture group
    echo $1             #2nd catpure group
    dosomethingwith $2  #3rd capture group
done

존재하다?


예시 텍스트:

blah12687hello=123
nothingthatmatches
blah3211hello=123456
blah15butnottheotherpattern

이전에 언급한 루프를 사용하면 다음과 같이 출력됩니다.

blah12687hello=123
12687
<it should run the command dosomethingwith 123>
blah3211hello=123456
3211
<it should run the command dosomethingwith 123456>

답변1

bash자체는 편의상 필요에 따라 캡처된 그룹에 대해 정규식 일치를 수행하는 방법을 제공합니다.

=~이중 괄호 안의 연산자는 [[연산자 왼쪽에 일치하는 문자열이 있고 오른쪽 피연산자로 정규식을 사용하여 표현식을 테스트합니다.

if [[ "$str" =~ $re ]]; then

표현식이 문자열과 일치하는 경우 문자열의 일치하는 부분이 배열에 저장되고 BASH_REMATCH캡처된 개별 그룹을 반복할 수 있습니다. 종료 상태는 0정규식이 일치하는지, 1일치하지 않는지, 2표현식이 유효하지 않은지 여부입니다.


예를 들어, 입력 라인을 배열에 저장하고 단어 blahhello고정 패턴을 저장한다고 가정해 보겠습니다.

#!/usr/bin/env bash

exampleStr=('blah12687hello=123' 'nothingthatmatches' 'blah3211hello=123456' 'blah15butnottheotherpattern')

re='blah([[:digit:]]+)hello=([[:digit:]]+)'

for str in "${exampleStr[@]}"; do
    if [[ "$str" =~ $re ]]; then
       for group in "${BASH_REMATCH[@]}"; do
           printf "%s\n" "$group"
       done
    else
       printf "No match \n"
    fi
done

위 코드에서 볼 수 있듯이 정규식을 true로 일치시키면 배열을 반복하여 BASH_REMATCH캡처된 각 그룹을 인쇄할 수 있습니다. 전체 스크립트 출력은 다음과 같습니다.

blah12687hello=123     # Value of BASH_REMATCH[0]
12687                  # Value of BASH_REMATCH[1]
123                    # Value of BASH_REMATCH[2]
Regex not matches.
blah3211hello=123456
3211
123456
Regex not matches.

보시다시피 BASH_REMATCH[0]정규식이 성공적으로 일치하는 문자열 부분은 항상 포함되며 캡처된 개별 그룹은 index 에서 시작하여 액세스할 수 있습니다 1. 캡처된 각 그룹을 처리하는 사용자 지정 논리를 작성할 수 있습니다. 이는 원래 의도했던 것과 정확히 같습니다.


파일 입력을 읽는 데 관심이 있다면 while처리하려는 파일에 대해 입력 리디렉션이 포함된 루프를 사용하세요.

while IFS= read -r line; do
    if [[ "$line" =~ $re ]]; then
       for group in "${BASH_REMATCH[@]}"; do
           printf "%s\n" "$group"
       done
    else
       printf "No match \n"
    fi
done < inputFile.txt

관련 정보