[unix] 휴대용 sed -e… db 또는! 비?

에서 편집
스테판 Chazelas가 POSIXifies (다시)sed삽입하여 형식 -expression 휴식 및 다른 -expression 문을. 자, 나는 그에게 그 의견에 왜 그에게 물을 수도 있지만, 그것은 이미 그 대답에 대한 개정 번호 18이며 ​​이전의 거의 대부분은 비슷한 공짜 덕분에 이미 감사했습니다 (삭제 된 의견을 볼 수 있다면 당신은 무엇을 알게 될 것입니다) 내 말은) . 또한, 나는 이것이 더 일반적으로 유용한 방식으로 이것을 표현하는 이유를 이해하기에 충분 하다고 생각 합니다. 그래서 여기에 바라고 있습니다 …

나는 일반적으로 가능한 경우 전체 sed -e노출 수를 1 로 유지하는 것을 선호 하지만 , 특히 차이가 a 와 a보다 크지 않을 때 가능한 한 사양 을 준수하는 것이 더 좋습니다 . 그러나 내가해야하는지 이해하지 못하면이 작업을 수행 할 수 없습니다 . 여기 내 이해의 현재 상태에 대한 간략한 설명이 있습니다.<space>-e

  • ' -e '휴식 이식 A의에 설 수있는 sed스크립트 \nA의 ewline 휴식 sed명령 줄 문 … 나는 이유에 대해 인정 하듯이 퍼지입니다

  • sed {함수 에서 닫는 괄호 }앞에는 다음 \n과 같이 ewline break 가 와야합니다 .

    • <right-brace>앞에는되어야 <newline>하고 앞에 나 올 수 있습니다 <blank>문자.
  • \newline 휴식 마찬가지로 …의 사용 다음 필요 a, b, c, i, r, t, w, 또는 :.

그러나 {함수 }정의가 !not 연산자 와 어떤 관련이 있는지 명확하게 이해하지 못합니다 . 사양 상태에서 부정 연산자에 대한 유일한 언급은 다음과 같습니다.

  • 함수 앞에는 하나 이상의 !문자 가있을 수 있으며 ,이 경우 주소가 패턴 공간을 선택하지 않으면 함수가 적용됩니다.

이것은 중괄호 사용이 중괄호를 !의미한다는 것을 의미 합니까? 어떤 명령- 나누기로 마찬가지로 분리해야 합니까? 이것이 스테판이 가장 최근에 POSIX 화 했을 때 해결 된 것입니까?{}$!' -e '

나는 그것이 !부정 연산자 라고 생각 하거나 b그가 편집 할 때 언급 한 목장 진술이거나 아마도 가능할 수도 있습니다. 그러나 나는 알지 못하고 좋아해야합니다. 이 경우 에만b 목장 문, 그때 저는 믿습니다 A가 d그 자리에서 할 수와의 필요성 제거 할 ' -e '틈을,하지만 난 오히려 세 번 hazarding 전에 어떤 것 POSIXified의 대답을. 도울 수 있니?

나는 위험을 감수 한 모든 후 가 아니라 어떤 큰 확실성, …



답변

그래서이 질문에 대한 답이 높을 때가 많았지 만 결국에는 거의 모든 경우 에이 작업을 올바르게 수행 하는 방법 을 직관적으로 해결했지만 최근에는 표준의 텍스트를 이해하는 것이 매우 구체적이었습니다. . 그것은 실제로 상당히 간단하게 언급되어 있습니다-나는 단지 어리석게 그것을 여러 번 간과했습니다.

텍스트의 관련 부분은 모두 제목 아래에 있습니다.

  • 의 명령 편집sed :

    • 인수 텍스트 는 하나 이상의 행으로 구성되어야합니다. \n텍스트에 포함 된 각 줄 바꿈 앞에는 \백 슬래시 가 와야 합니다. 텍스트의 다른 백 슬래시는 제거하고 다음 문자는 문자 그대로 처리해야합니다.

    • rw명령 동사 및 w받는 플래그 s명령은 선택적 취할 rfile (또는 에 WFile 하나 이상의 문자 또는 플래그 동사 명령 분리) 파라미터를, <blank>s; 구현은 확장으로서 제로 분리를 허용 할 수있다.

    • 명령 이외의 동사 {, a, b, c, i, r, t, w, :, 및 #a로 올 수 있습니다 ;세미콜론, 옵션 <blank>s, 또 다른 명령 동사. 그러나 s명령 동사를 w플래그 와 함께 사용하는 경우이 방법으로 다른 명령을 사용하면 정의되지 않은 결과가 생성됩니다.

…에…

  • 옵션 : 여러 -e-f옵션을 지정할 수 있습니다. 모든 명령은 원본에 관계없이 지정된 순서대로 스크립트에 추가되어야합니다.

    • -e 스크립트 -에 의해 지정된 편집 명령 추가 스크립트 의 마지막에 옵션 인수 스크립트 편집 명령을. 스크립트 옵션 – 인수는 같은 특성을 가진다 스크립트 에 설명 연산자, 피연산자 절을 참조하십시오.

    • -f script_file은 – 파일의 편집 명령을 추가 script_file 스크립트의 끝.

그리고 마지막으로 …

  • 피연산자 :

    • 스크립트 – 문자열이로 사용되는 스크립트 편집 명령. 응용 프로그램 은 최종 문자가 ewline 일 필요가 없다는 것을 제외하고 텍스트 파일의 제한을 위반 하는 스크립트 를 제시해서는 안됩니다 \n.

따라서, 당신이 그것을 모두 취할 때, 선택적으로 뒤에 오는 사전 정의 된 구분자가없는 임의의 매개 변수가 오는 명령은 ( s d sub d repl d flag예를\n 들어와 달리) 이스케이프되지 않은 ewline 에서 구분해야한다는 것이 합리적입니다.

그 논란의 여지가있다 ; 입니다 사용하여 미리 정의 된 구분하지만,이 경우 ;의에 대한 [aic]별도의 사용 파서에서입니다 – 별도의 파서는이 세 가지 명령을 위해 특별히 구현에 포함 할 것을 필요로 할 명령을 [:brw]예를 들어이. 그렇지 않으면 구현시 텍스트 매개 변수 내에서 백 슬래시 이스케이프 처리 를 요구해야하며 그 이후로 ; 더 복잡해집니다.

경우 내가 쓰기 한 sedI 준수하고 효율적으로 둘 수 원하는 어떤을, 그때는 별도의 파서를 쓸 것입니다, 나는 기대 – 어쩌면 제외 [aic]해야 세대 구문 오류를 바로 다음에하지 않을 경우 \newline. 그러나 이는 간단한 토큰 화 문제입니다. 끝 구분 기호는 일반적으로 더 문제가됩니다. 나는 그것을 그렇게 쓸 것입니다 :

sed -e w\ file\\ -e one -e '...;and more commands'

…과…

sed -e a\\ -e appended\\ -e text -e '...;and more commands'

… 첫 번째는 다음과 같은 이름의 파일을 작성하고 작성한다는 점에서 매우 유사하게 작동합니다.

file
one

… 두 번째는 다음과 같이 출력시 현재 줄에 텍스트 블록을 추가합니다 …

appended
text

… 모두 매개 변수에 대해 동일한 구문 분석 코드를 공유하기 때문입니다.

그리고 관련 { ... }$!문제를 – 글쎄, 나는 방법이 떨어져 있었다. 주소 앞에 하나의 명령은 하지 함수 아니라, 그것은 단지 명령을 해결합니다. 주석레이블 정의를 제외하고 함수 정의를 포함하여 거의 모든 명령 이 수락 또는 주소 로 지정됩니다 . 주소는 줄 번호 또는 정규 표현식 일 수 있으며로 부정 될 수 있습니다 . 그래서 …{ }/one//one/,/two/#:!

$!d
/address/s/ub/stitution/
5!y/d/c/

;표준에 따라 더 많은 명령 이 뒤따를 수 있지만 단일 주소에 더 많은 명령이 필요하고 각 명령을 실행 한 후에 해당 주소를 재평가해서는 안되는 경우 {함수 }는 다음 과 같이 사용해야합니다.

/address/{ s//replace addressed pattern/
           s/do other conditional/substitutions/
           s/in the same context/without/
           s/reevaluating/address/
}

{같은 줄에서 닫는 것으로 이어질 수 없으며 줄 의 시작을 제외하고 }는 닫을 }수 없습니다. 그러나 포함 된 명령 다음에 \newline이 없어야하는 경우에는 함수 내에있을 필요도 없습니다. 따라서 위의 모든 s///ubstitution과 심지어 닫는 }괄호 뒤에는 ;세미콜론과 추가 명령이 올 수 있습니다.

나는 \newline 구분 기호 에 대해 계속 이야기 하지만 문제는 대신 xpression -e명령문 에 관한 것입니다. 그러나 둘은 실제로 하나이며 동일합니다. 핵심 관계는 스크립트 가 리터럴 명령 행 인수 또는 파일 중 하나가 될 수 있고 -[ef]둘 다 텍스트 파일로 해석된다는 것 입니다. \newline) 그러나 실제로 는 ewline으로 끝날 필요 는 \n없습니다. 이것에 의하여 나는 reasonbly 수 있습니다 (I 희망) • 그래도 추론 \0NUL구분 된 인수가 끝나는 의미 \n모든 호출 인수를 얻을로 ewline, 그리고 ) 적어도\0NUL 어쨌든 구분 기호를, 다음 중 하나를 잘 작동합니다.

실제로, 표준에서 \백 슬래시 이스케이프 처리 줄 바꿈을 지정하는 경우를 제외하고 는 항상 필요한 경우가 많았습니다.

sed -e ... -e '...\' -e '...'

… 잘 작동합니다. 그리고 모든 경우에-다시, 실제로-탈출하지 않은 \newline이 필요한 곳 ​​…

sed -e '...' -e '...'

… 나도 일 했어. 위에서 언급 한 예외는 …

sed -e 's/.../...\' -e '.../'

… 내 테스트 중 어떤 구현에서도 작동하지 않습니다. 나는 텍스트 파일 요구 사항과 구분 기호와 함께 s/// 제공 되는 사실로 돌아가서 단일 문이 \0NUL구분 된 인수에 걸쳐 있어야 할 이유가 없다고 확신합니다 .

결론적으로 다음은 여러 종류의 sed명령 을 작성하는 이식 가능한 방법에 대한 간략한 설명입니다 .

다음 중 하나에 해당 [aic]:

...commands;[aic]\
text embedded newline\
delimiting newline
...more;commands...

…또는…

sed -e '...commands;[aic]\' -e 'text embedded newline\' -e 'delimiting newline' -e '.;.;.'

의 위해 [:rwtb]를 Where 매개 변수 입니다 옵션 (모든하지만 대한 :) 하지만, 단락 문자 \newline는 없습니다 . 참고 여러 개의 라인 시도 할 이유가 없었 것을 라벨 에 사용되는 등의 매개 변수를 [:tb]하지만 writing는 / r여러 라인에 eading [RW] 파일 의 매개 변수는 일반적으로 의심없이 받아 들여 sed내가 임베디드로 너무 오래 테스트 한의 \newline ▶ / 이스케이프 \백 슬래시. 그럼에도 불구하고 표준에서는 레이블[rw] 파일 매개 변수가 텍스트와 동일하게 구문 분석되어야한다는 것을 직접 지정하지 않습니다.\n처음 두 개와 관련하여 ewline에 대해서는 언급하지 않습니다 .

...commands;[:trwb] parameter
...more;commands...

…또는…

sed -e '[:trwb] parameter' -e '...'

<space>위의 경우 선택 사항입니다 [:tb].

그리고 마침내…

...;address[!]{ ...function;commands...
};...more;commands....

…또는…

sed -e '...;address[!]{ ...function;commands...' -e '};...more;commands...'

… 상기 명령의 경우 (제외하고는 :) 도 하나 이상의 동의 주소를 하고있는이 일 수있다 /정규 표현식 /이나 행 번호와 함께 부정 할 수있는 !하나 개 이상의 명령의 하나의 평가를 위해 필요한 경우, 그러나 주소 다음 {함수 컨텍스트 }구분 중괄호를 사용해야합니다. 함수에는 여러 개의 \newline으로 구분 된 명령이 포함될 수 있지만 각각은 중괄호 내에서 구분해야합니다.

그것이 휴대용 sed스크립트 를 작성하는 방법 입니다.


답변