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
“욕심 많은”일치 만 지원하므로 첫 번째. *가 나머지 줄과 일치합니다. 부정한 문자 클래스를 사용하여 탐욕스럽지 않은 일치를 달성하거나 sed
Perl과 호환되는 버전 또는 정규식에 대한 다른 확장을 사용하지 않는 한 패턴 공간 (줄)에서 정확한 패턴 일치를 추출 할 수 없습니다. ).
답변
awk
with 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]*$//'