sed에서 느낌표를 여러 개 사용하는 이유는 무엇입니까?

sed에서 느낌표를 여러 개 사용하는 이유는 무엇입니까?

POSIX sed 문서설명하다:

함수 앞에는 하나 이상의 "!" 문자가 올 수 있으며, 이 경우 주소가 패턴 공간을 선택하지 않으면 함수가 적용되어야 합니다. 첫 번째 '!' 문자 앞에는 0개 이상의 <공백> 문자가 허용됩니다. <공백> 문자가 '!' 문자 뒤에 올 수 있는지 여부는 지정되지 않으며, 해당 애플리케이션은 <공백> 문자와 함께 '!' 문자를 존중해서는 안 됩니다.

따라서 POSIX sed를 사용하면 다음을 수행할 수 있습니다.

sed -e '/pattern/!d' file

이는 다음과 같이 쓰는 것과 같습니다.

sed -e '/pattern/!!d' file

느낌표 !!!dn여전히 작동합니다(세 가지 sed버전 포함).가보 도구 상자). 느낌표가 하나 이상 여러 개 있으면 아무런 이점이 없다고 생각합니다.

사양에서 이 구문을 허용하는 이유는 무엇이며 실제 애플리케이션에서 어떻게 유용합니까?


이 경우 GNU sed는 호환되지 않는 것 같습니다. 느낌표를 여러 개 사용하면 불평합니다.

$ sed -e '/pattern/!!d' file
sed: -e expression #1, char 11: multiple `!'s

답변1

sedAPI는 매우 원시적입니다. 이는 의도적으로 설계된 것입니다. 적어도 그것은머무르다독창적인 디자인 - 애초에 원래 디자인되었는지 여부는 알 수 없습니다. 대부분의 경우 sed실행 시 출력되는 스크립트를 작성합니다.다른 sed스크립트참으로 간단한 일이다. 매크로 전처리기(예: 및/또는 )는 sed종종 이러한 방식으로 적용됩니다.m4make

(다음은 매우 가설적인 사용 사례입니다. 이는 솔루션에 맞게 설계된 문제입니다. 이것이 다소 어렵다고 생각되면 아마도 그렇기 때문일 것입니다. 그러나 이것이 반드시 덜 효과적인 것은 아닙니다.)


다음 입력 파일을 고려하십시오.

cat <<"" >./infile
camel
cat dog camel
dog cat
switch
upper
lower

sed단어를 추가하는 스크립트를 작성하려면-사례각각의 끝까지적합한위 입력 파일의 한 줄에서 단어를 찾을 수 있는 경우에만적절한 배경우리는 최대한 효율적으로 하고 싶어(이것이 우리의 목표여야 합니다(예: 컴파일 작업 중).)/그렇다면 정규식을 최대한 적용하지 말아야 합니다 ./

우리가 할 수 있는 한 가지는 파일을 시스템에서 즉시 사전 편집하고 sed컴파일하는 동안 전혀 호출하지 않는 것입니다. 그러나 로컬 설정 및/또는 컴파일 시간 옵션에 따라 파일에 이러한 단어가 포함되거나 포함되지 않아야 하는 경우 그렇게 하는 것은 이상적인 옵션이 아닐 수 있습니다.

우리가 할 수 있는 또 다른 일은 파일을 처리하는 것입니다.지금정규 표현식에 반대합니다. 우리는 라인 번호를 기반으로 편집할 수 있는 스크립트를 생성하여 컴파일에 포함할 수 있습니다. sed이는 장기적으로 더 효율적인 경로인 경우가 많습니다.

예를 들어:

n=$(printf '\\\n\t')
grep -En 'camel|upper|lower' <infile |
sed "   1i${n%?}#!/usr/heirloom/bin/posix2001/sed -nf
        s/[^:]*/:&$n&!n;&!b&$n&/;s/://2;\$a${n%?}q"'
        s/ *cat/!/g;s/ *dog/!/g
        s| *\([cul][^ ]*\).*|s/.*/\1-case/p|'

sed... 다음과 같은 스크립트로 출력을 작성합니다 ...

#!/usr/heirloom/bin/posix2001/sed -nf
:1
    1!n;1!b1
    1s/.*/camel-case/p
:2
    2!n;2!b2
    2!!s/.*/camel-case/p
:5
    5!n;5!b5
    5s/.*/upper-case/p
:6
    6!n;6!b6
    6s/.*/lower-case/p
q

./bang.sed이 출력이 내 컴퓨터의 실행 가능한 텍스트 파일인 and run 에 저장되면 ./bang.sed ./infile출력은 다음과 같습니다.

camel-case
upper-case
lower-case

이제 나에게 물어볼 수도 있습니다 ...왜 이 일을 해야 합니까? 그냥 grep게임을 스트리밍하면 안 되나요 ? 어쨌든 낙타 케이스를 사용하는 사람은 누구입니까?각 질문에 대해서만 대답할 수 있습니다.나는 전혀 모른다 ...난 그런 짓 안 하거든요. 나는 개인적으로 이 질문을 읽기 전에는 전혀 눈치 채지 못했습니다.많은-!사양의 요구 사항을 구문 분석하는 것은 매우 깔끔한 캡처라고 생각합니다.

이것많은-!물건했다그러나 그것은 나에게 즉시 의미가 있습니다. 대부분의 sed사양은 간단한 구문 분석과 간단한생성됨 sed스크립트. 이 경우 필수 \newline 구분 기호가 더 적합하다는 것을 알 수 있으며 [wr:bt{], 이 아이디어를 염두에 둔다면 사양의 다른 측면을 더 잘 이해할 수 있습니다.(예: :어떤 주소도 허용하지 않고 q1개 이상의 주소도 허용하지 않음).

위의 예에서 나는 sed다음과 같은 스크립트 형식을 작성했습니다.한 번한 번 읽어보세요. 자세히 살펴보면 sed편집 파일을 읽을 때 한 명령 블록에서 다음 명령 블록으로 진행한다는 것을 알 수 있습니다. 편집 파일을 완전히 완료할 때까지 편집 스크립트를 분기하거나 완료하지 않습니다.

제 생각에는많은-!주소는 다른 경우보다 이 경우에 더 유용할 수 있지만 솔직히 이를 잘 활용할 수 있는 경우는 단 한 번도 생각나지 않습니다 sed. 나는 또한 GNU/BSD가 지정된 방식으로 이를 처리하지 않는다는 점에 주목할 가치가 있다고 생각합니다 sed. 이는 아마도 사양에서 많이 요구되는 측면이 아니므로 구현이 이를 무시하면 매우 심각하게 의심될 것입니다.곤충@결과적으로 상자가 심각하게 손상될 수 있습니다.

즉, 문제가 규정대로 처리되지 않았습니다.규정을 준수하는 것처럼 가장하는 구현은 버그가 있을 수 있으므로 여기에서 관련 개발자에게 이메일을 보내는 것이 타당하다고 생각하며 그렇지 않은 경우 그렇게 할 계획입니다.

관련 정보