sed에서 패턴 발생만 인쇄하는 방법은 무엇입니까?

sed에서 패턴 발생만 인쇄하는 방법은 무엇입니까?

내 Linux 컴퓨터에 세미콜론으로 구분된 데이터가 있습니다. N 번째(예를 들어 3d) 단어를 찾아 전체 줄 대신 인쇄해야 합니다. 필요한 패턴을 찾아 그 사이에 배치하여 _작동하는 것을 확인하는 다음 스크립트가 있습니다.

sed 's/\;[^;]*\;/_&_/3'

이 입력의 예를 들면 다음과 같습니다.

A1a 77l;a3sSs 2 smm;AS 3N123N8j a5njs;M3Xa 4 4a 3n1J  S2a;sm i;A9S;dd d3

다음과 같이 출력됩니다.

A1a 77l;a3sSs 2 smm;AS 3N123N8j a5njs;M3Xa 4 4a 3n1J  S2a;sm i_;A9S;_dd d3

이제 패턴을 찾았을 때 전체 줄 대신 간단히 인쇄하여 출력은 다음과 같습니다.

A9S

답변1

sed -E 's/(([^;]*);){6}.*/\2/'

6캡처하려는 필드 번호는 어디에 있습니까 ?

(입력의 필드 수보다 큰 필드 번호를 지정하면 대체 없이 입력만 에코됩니다.)

저는 -E확장 정규식을 활성화하는 이 옵션을 사용했습니다. 사용 중인 sed 버전에 따라 -r이를 사용해야 할 수도 있습니다. 또는 기본 정규 표현식을 사용하고 괄호와 중괄호를 이스케이프 처리하려면 이 옵션을 건너뛰세요.

sed 's/\(\([^;]*\);\)\{6\}.*/\2/'

작동 방식:

sed는 가능한 가장 빠른 위치에서 일치 항목을 찾습니다. 이 경우 첫 번째 문자부터 시작하는 일치 항목을 찾습니다(입력에 6개 이상의 필드가 있다고 가정). 외부 대괄호 표현식은 필드 뒤에 구분 기호가 오는 것과 일치합니다 ;. 명령은 6이들(또는 지정한 숫자)을 연속적으로 일치시킵니다. 끝에 있는 것이 .*나머지 줄과 일치합니다. 그 결과 생산라인 전체가 교체됐다.

무엇으로 대체될까요? \2내부 대괄호 표현식(두 번째 왼쪽 대괄호로 시작하는 표현식)을 나타냅니다. 내부 괄호 표현식은 실제로 6번 일치하지만 sed는 사용자가 원하는 마지막 일치 항목을 사용합니다.

더 나은 기능을 갖춘 버전:

이 버전은 표시된 필드가 존재하지 않는 경우 전체 줄을 빈 문자열로 바꿉니다(예: 입력에 6개 미만의 필드가 있는 경우).

sed -E 's/(([^;]*);){6}.*/\2/;t;d'

OS X의 sed 버전(또는 BSD?)에서는 다음 두 줄로 작성해야 하는 것 같습니다.

sed -E 's/(([^;]*);){6}.*/\2/;t
d'

t대체가 이루어지면 이 명령은 이 입력 라인에 대한 sed의 처리를 종료합니다.

따라서 6번째 필드가 존재하는 경우 이전과 같이 교체가 수행되고 t명령은 이 입력 라인의 처리를 종료합니다. 그러나 6번째 필드가 존재하지 않으면 s명령은 교체를 수행하지 않으므로 t분기되지 않습니다. sed는 d입력 줄을 삭제하는 명령을 계속 진행합니다(입력 줄에 필드가 6개 미만인 경우). , 그것이 우리가 원하는 것입니다).

답변2

;파일에서 세 번째로 구분된 필드를 가져오려면 다음을 사용하십시오 cut.

$ cut -d ';' -f 3 file
AS 3N123N8j a5njs

표시된 필드를 얻으려면 6번째 필드를 잘라냅니다.

$ cut -d ';' -f 6 file
A9S

awk를 사용하여 이 작업을 수행 할 수도 있습니다 awk -F ';' '{ print $6 }' file.

의 경우 대체해야 하기 때문에 명령 의 플래그 ( 숫자)를 sed사용할 수 없습니다./nsn전반적으로. 이것은 실제로 포함됩니다성냥특정 영역만이 아닌 전체 제품군.

따라서 ;여섯 번째로 구분된 필드를 얻는 한 가지 방법은 다음을 사용하는 것입니다.

$ sed 's/^\([^;]*;\)\{5\}\([^;]*\);.*/\2/' file
A9S

또는 sed확장 정규 표현식을 지원하는 -E경우

$ sed -E 's/^([^;]*;){5}([^;]*);.*/\2/' file
A9S

즉, 각각 일치하는 5개 필드 [^;]+;(각 필드의 종료 포함 ;), 그 다음 필드, 나머지 줄을 일치시킵니다. 이 항목을 모두 원하는 필드로 바꾸세요.

즉, 이 작업에는 cut또는 를 사용하는 것이 더 좋습니다.awk

관련 정보