Sed에서 이름 앞의 단어 검색

Sed에서 이름 앞의 단어 검색

이 스레드는 이 스레드에 대한 링크에 있는 산술 명령에 의해 동기가 부여됩니다.여기Sed에서 역방향 산술을 수행하고 싶습니다.

데이터

Mikael symptom
David symptom
hello symptom

이 명령은 처음 두 항목을 반환해야 합니다. Perl의 Lookbehind는 한 가지 방법이지만 Sed가 그것을 할 수 있는지 확인하고 싶었습니다.

의사코드의 메소드

  • 일치하는 이름: g/[A-Z]\w\w/;is.words[2]('symptom')

뒤를 봐

  • Match symptom; 다음 이름을 찾습니다. 이름이 있으면 반환합니다.

Sed에서 이 의사코드를 작성할 수 있나요?

답변1

sed '/^[[:upper:]][[:lower:]]\{1,\} symptom$/!d
    H;x;/^\n/!q;s///;x;d'

이렇게 하면 대문자로 시작하고 그 뒤에 하나 이상의 소문자가 오는 줄을 찾은 다음 하나만 찾습니다.<스페이스>그리고 문자열징후. 현재 줄이 일치하지 않으면 d삭제되고 다음 입력 줄부터 스크립트가 맨 위에서 다시 시작됩니다.

그 경우하다일치 항목은 H삽입된 줄 구분 기호 뒤의 이전 공백 에 복사됩니다 \n. 이런 일이 처음 발생하면 h기존 공간은 비어 있을 것이므로 주인공은 \n유라인이 됩니다. 일치하는 라인이 H삭제 된 후 h이전 및 패턴 공간이 xe에 의해 변경됩니다. 만약 있다면!아니요\n패턴 공간에서 ewline을 리드한 다음 sed q입력을 충족합니다. 갑자기 추가 입력 읽기가 중단되었습니다.(또는 스크립트에서 더 많은 명령을 실행합니다. 예를 들어 d)별말씀을요. 그러나 리딩 \n라인이 제거되고 h오래된 패턴 공간이 x다시 변경되어 패턴 공간이 d제거됩니다.

결과적으로 처음 만난 행은 유지되고 그것이 나타내는 첫 번째 발생 태그는 이를 quitting 입력에서 저장하지만두번째발생하면 처리를 종료합니다.

하지만 내가 오해한 건 아닐까? 파일에서 처음 두 개의 일치 항목만 원한다는 것이 무슨 뜻인지 이해합니다.

당신이 원한다면이름만약에증상$이것은 매우 간단합니다.

sed -n '/^[[:upper:]][[:lower:]]\{1,\} [^ ]*$/s/ symptom$//p'

여기서는 우리가 실제로 찾고 있는지 확인합니다.가능한교체를 시도하기 전에 라인을 일치시키세요 s///- s///교체가 다음과 같기 때문입니다.기능부모 주소. true인 경우 원하지 않는 꼬리를 잘라내고 p성공할 경우 에만 인쇄하려고 합니다 .둘 다머리와 꼬리 상태를 확인하기 전에.

답변2

내가 이해하는 바에 따르면, 대문자 단어와 그 뒤에 대문자 단어가 포함된 줄을 인쇄하고 싶습니다 symptom. 이 경우:

$ sed -rn '/\b[[:upper:]][[:lower:]]*[[:space:]]+symptom/p' data
Mikael symptom
David symptom

편의상 \bwhich를 사용하여 단어 경계를 나타냅니다. 이는 최소한 GNU sed에서 지원됩니다. 귀하의 sed가 지원하지 않는 경우 알려주십시오.

작동 방식:

기본 형태는 다음과 같습니다.

sed -n '/pattern/p' file

이것은 일치하는 줄만 인쇄합니다 pattern. 우리의 경우 패턴에는 다음이 포함됩니다.

  • \b

    이는 단어 경계에서만 일치합니다.

  • [[:upper:]][[:lower:]]*

    이는 대문자 뒤에 0개 이상의 소문자가 오는 것과 일치합니다.

    고대에는 이것이 이렇게 쓰여졌을 수도 있다는 점에 유의하십시오 [A-Z][a-z]+. 유니코드로 인해 현재는 신뢰할 수 없습니다. 위의 내용은 문자 클래스를 사용하므로 upper유니 lower코드에 안전합니다.

  • [[:space:]]+symptom

    이는 하나 이상의 공백 뒤에 단어가 오는 것과 일치합니다 symptom.

선택하다

앞의 이름만 인쇄하고 싶다고 가정해 보겠습니다 symptom.

$ sed -rn 's/\b([[:upper:]][[:lower:]]*)[[:space:]]+symptom.*/\1/p' data
Mikael
David

답변3

sed -n '/^[[:upper:]]\w* symptom/s/ .*//p'

대문자로 시작하는 줄을 인쇄한 symptom다음 첫 번째 단어를 제외한 모든 항목을 삭제합니다.

관련 정보