![awk 또는 grep을 사용하여 그룹 캡처](https://linux55.com/image/119041/awk%20%EB%98%90%EB%8A%94%20grep%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EA%B7%B8%EB%A3%B9%20%EC%BA%A1%EC%B2%98.png)
발견된 각 패턴을 반복하고 루프 내에서 다른 캡처 그룹에 액세스하고 싶습니다. 가능 하면 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
표현식이 유효하지 않은지 여부입니다.
예를 들어, 입력 라인을 배열에 저장하고 단어 blah
와 hello
고정 패턴을 저장한다고 가정해 보겠습니다.
#!/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