sed, awk 또는 gawk를 사용하여 검색 및 바꾸기와 같은 작업을 수행하는 방법에 대한 많은 예제와 매뉴얼 페이지를 봅니다.
하지만 제 경우에는 특정 값을 추출하기 위해 텍스트 파일에 대해 실행하려는 정규식이 있습니다. 검색 및 바꾸기를 원하지 않습니다. 이것은 bash에서 호출됩니다. 예를 들어 보겠습니다.
정규 표현식의 예 :
.*abc([0-9]+)xyz.*
입력 파일 예 :
a
b
c
abc12345xyz
a
b
c
간단하게 들리지만 sed / awk / gawk를 올바르게 호출하는 방법을 알 수 없습니다. 내가 원하는 것은 bash 스크립트 내에서 다음과 같습니다.
myvalue=$( sed <...something...> input.txt )
내가 시도한 것은 다음과 같습니다.
sed -e 's/.*([0-9]).*/\\1/g' example.txt # extracts the entire input file
sed -n 's/.*([0-9]).*/\\1/g' example.txt # extracts nothing
답변
내 sed(Mac OS X)가 +. *대신 시도 하고 p인쇄 일치 태그를 추가했습니다 .
sed -n 's/^.*abc\([0-9]*\)xyz.*$/\1/p' example.txt
없이 하나 이상의 숫자를 일치 시키 +려면 다음을 사용합니다.
sed -n 's/^.*abc\([0-9][0-9]*\)xyz.*$/\1/p' example.txt
답변
sed를 사용하여이 작업을 수행 할 수 있습니다.
sed -rn 's/.*abc([0-9]+)xyz.*/\1/gp'
-n결과 라인을 인쇄하지 마십시오-r이렇게하면 캡처 그룹 괄호를 탈출 할 수 없습니다().\1포획 그룹 경기/g글로벌 경기/p결과를 인쇄
이 작업을 더 쉽게 만들어주는 도구 를 직접 작성했습니다.
rip 'abc(\d+)xyz' '$1'
답변
나는 perl이것을 더 쉽게 만들기 위해 사용 합니다. 예 :
perl -ne 'print $1 if /.*abc([0-9]+)xyz.*/'
이것은 Perl을 실행하고이 -n옵션은 Perl이 STDIN에서 한 번에 한 줄씩 읽고 코드를 실행하도록 지시합니다. 이 -e옵션은 실행할 명령을 지정합니다.
이 명령어는 read 행에서 regexp를 실행하고 일치하는 경우 첫 번째 중괄호 ( $1) 세트의 내용을 인쇄합니다 .
당신은 또한 끝에 여러 파일 이름을 할 수 있습니다. 예 :
perl -ne 'print $1 if /.*abc([0-9]+)xyz.*/' example1.txt example2.txt
답변
버전 경우 grep지원을 당신이 사용할 수있는 -o인쇄 옵션을 단지 당신의 정규 표현식 일치하는 모든 라인의 일부를.
그렇지 않다면 여기에 sed내가 생각 해낼 수 있는 최선의 방법이 있습니다 .
sed -e '/[0-9]/!d' -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'
… 숫자없이 삭제 / 건너 뛰고 나머지 행의 경우 모든 선행 및 후행 숫자가 아닌 문자를 제거합니다. (나는 당신의 의도가 하나를 포함하는 각 줄에서 숫자를 추출하는 것이라고 추측하고 있습니다).
다음과 같은 문제 :
sed -e 's/.*\([0-9]*\).*/&/'
…. 또는
sed -e 's/.*\([0-9]*\).*/\1/'
… sed“욕심 많은”일치 만 지원하므로 첫 번째. *가 나머지 줄과 일치합니다. 부정한 문자 클래스를 사용하여 탐욕스럽지 않은 일치를 달성하거나 sedPerl과 호환되는 버전 또는 정규식에 대한 다른 확장을 사용하지 않는 한 패턴 공간 (줄)에서 정확한 패턴 일치를 추출 할 수 없습니다. ).
답변
awkwith match()를 사용하여 캡처 된 그룹에 액세스 할 수 있습니다 .
$ awk 'match($0, /abc([0-9]+)xyz/, matches) {print matches[1]}' file
12345
이것은 패턴을 일치 시키려고합니다 abc[0-9]+xyz. 그렇게하면 matches첫 번째 항목이 block 인 array에 슬라이스를 저장합니다 [0-9]+. match() 해당 하위 문자열이 시작되는 문자 위치 또는 인덱스를 반환 하므로 (문자열의 시작 부분에서 시작하는 경우 1)print 작업을 트리거합니다 .
으로 grep당신은 모양 숨김 및보기 미리 사용할 수 있습니다 :
$ grep -oP '(?<=abc)[0-9]+(?=xyz)' file
12345
$ grep -oP 'abc\K[0-9]+(?=xyz)' file
12345
이 체크 패턴 [0-9]+이 내에서 발생 abc하고 xyz그냥 숫자를 인쇄합니다.
답변
perl은 가장 깨끗한 구문이지만 perl이 없으면 (항상 그런 것은 아닙니다) 정규식의 gawk와 구성 요소를 사용하는 유일한 방법은 gensub 기능을 사용하는 것입니다.
gawk '/abc[0-9]+xyz/ { print gensub(/.*([0-9]+).*/,"\\1","g"); }' < file
샘플 입력 파일의 출력은
12345
참고 : gensub는 전체 정규식 (// 사이)을 대체하므로 대체에서 숫자 앞뒤의 텍스트를 제거하려면 ([0-9] +) 앞뒤에. *를 넣어야합니다.
답변
라인을 선택하려면 원하지 않는 비트를 제거하십시오.
egrep 'abc[0-9]+xyz' inputFile | sed -e 's/^.*abc//' -e 's/xyz.*$//'
기본적으로 원하는 줄을 egrep선택한 다음 sed숫자 앞뒤의 비트를 제거하는 데 사용 합니다.
여기에서 실제로 작동하는 것을 볼 수 있습니다.
pax> echo 'a
b
c
abc12345xyz
a
b
c' | egrep 'abc[0-9]+xyz' | sed -e 's/^.*abc//' -e 's/xyz.*$//'
12345
pax>
업데이트 : 분명히 실제 상황이 더 복잡하다면 RE를 수정해야합니다. 예를 들어 시작과 끝에서 항상 0 개 이상의 비 숫자 내에 단일 숫자가 묻혀있는 경우 :
egrep '[^0-9]*[0-9]+[^0-9]*$' inputFile | sed -e 's/^[^0-9]*//' -e 's/[^0-9]*$//'
