sed에서 특정 패턴을 다른 패턴보다 "우선순위"로 지정하는 방법은 무엇입니까?

sed에서 특정 패턴을 다른 패턴보다 "우선순위"로 지정하는 방법은 무엇입니까?

이 sed 필터가 있습니다.

/.*[1-9][0-9][0-9] .*/{
        s/.*\([1-9][0-9][0-9] .*\)/\1/
}

/.*[1-9][0-9] .*/{
        s/.*\([1-9][0-9] .*\)/\1/
}

/.*[0-9] .*/{    # but this is always preferred/executed
        s/.*\([0-9] .*\)/\1/
}

문제는 처음 두 개가 더 제한적이고 마지막 세 번째가 처음 두 개를 포함하기 때문에 더 "강력"하기 때문에 시행되지 않는다는 것입니다. sed가 "우선 순위"를 사용하여 처음 두 개를 가져오도록 하는 방법이 있습니까? 좋다

if the first matches
    do first things
elif the second matches
    do second things
elif the third matches
    do third things

답변1

이러한 정규 표현식의 대상이 무엇인지 모르고 테스트 데이터도 없는 경우 필요한 것은 스크립트 끝으로 분기하고 교체가 성공적으로 완료되면 나머지 코드 처리를 건너뛰도록 하는 t분기입니다 .sed

sed '/regexp1/ s/do/things/; t
     /regexp2/ s/do/things/; t
     /regexp3/ s/do/things/ ' infile

사용하는 명령어에 따라 b분기(무조건 지정된 레이블로, 레이블이 생략된 경우 스크립트 끝으로)를 사용할 수도 있습니다 sed -e '/regex/{ s/do/things/; b' -e '}; ...'.


"man sed"에서:

t label
마지막 입력 행을 읽은 이후 as///가 성공적으로 교체된 경우 레이블로 분기하고 레이블이 생략된 경우 마지막 t 또는 T 명령 이후 스크립트 끝으로 분기합니다.

b label은
label로 분기되며, label이 생략되면 스크립트 끝으로 분기됩니다.

답변2

당신은 무슨 일이 일어나고 있는지 오해했습니다. Sed는 항상 일치하는 모든 패턴을 순서대로 실행합니다. 문제는 마지막 스키마가 첫 번째 스키마의 내용을 다시 편집한다는 것입니다.

또한 s///의 검색 패턴이 일치 패턴과 동일한 경우 중복된 것이며 실제로 패턴 간에 다르게 변경되지 않는데 어떤 패턴이 실행되고 있는지 어떻게 알 수 있습니까?

관련 정보