sed: "개행 문자를 제외한 모든 문자"를 일치시키는 휴대용 솔루션

sed: "개행 문자를 제외한 모든 문자"를 일치시키는 휴대용 솔루션

개행 문자를 다음과 일치시킬 수 있습니다 \n.

echo "one
two" | sed 'N;s/\n/_/g'

GNU에서는 개행 문자를 제외한 모든 문자를 일치시킬 sed수 있습니다 .[^\n]

echo "one
two" | sed 'N;s/[^\n]/_/g'

이는 매우 편리하지만 POSIX를 위반합니다. 다른 버전 sed에 대한 정답__n______

탭과 동일하지만 실제 탭(앞에 ctrl-v)을 사용하여 해결할 수 있었습니다. 그러나 이것은 개행 문자에서는 작동하지 않습니다.

echo "one
two" | sed 'N;s/[^
]/_/g'

나에게주세요 unbalanced brackets.

[^[:cntrl:]]일치시키려는 다른 제어 문자가 없는 경우에만 를 사용하면 됩니다.

그렇다면 POSIX에서 개행 문자를 제외한 모든 문자를 일치시키는 올바른 방법은 무엇입니까 sed?

답변1

귀하의 질문을 정확하게 이해하지 못했을 수도 있지만 답변해 드리겠습니다.

개행 문자를 제외한 모든 문자를 일치시키려면 간단한 정규식 점이 .정확하게 해당 작업을 수행합니다. 개행 문자를 제외한 모든 문자와 일치합니다.

Gnu가 아닌 sed로 시도해 보겠습니다.

$ cat file5
home
help
variables
compatibility

$ sed 's/./_/g' file5
____
____
_________
_____________

$ echo "one
two
three
four" |sed 's/./_/g'
___
___
_____
____

그런데 첫 번째 sed 예는 다음과 같습니다.

echo "one
two" | sed 'N;s/\n/_/g'

모든 새 줄이 아닌 다음 새 줄에만 일치합니다.

$ echo "one
> two
> three
> four" |sed 'N;s/\n/_/g'
one_two
three_four

답변2

기본 정규식에 대한 POSIX 사양리터럴 개행 문자 일치는 허용되지 않습니다 \n(아래 강조):

POSIX.1-2017의 셸 및 유틸리티 볼륨은 <newline>정규식을 사용하는 표준 유틸리티에 대한 별도의 설명에서 문자 일치를 허용하는지 여부를 지정합니다.<newline>달리 지정하지 않는 한, 패턴이나 일치 텍스트에 리터럴 문자나 동등한 이스케이프 시퀀스를 사용하면 정의되지 않은 결과가 생성됩니다..

다행스럽게도,sed유틸리티 사양별도의 언급이 있는 경우 다음 텍스트를 포함합니다.

유틸리티 sed는 XBD 기본 정규식에 설명된 대로 다음을 추가하여 BRE를 지원해야 합니다.

[...]

  • 이스케이프 시퀀스는 패턴 공간의 임베딩과 일치 \n해야 합니다 . <newline>[...]

이를 통해 패턴 공간이 포함된 정규식에 사용된 리터럴 개행 문자를 일치시킬 수 있습니다(eg 사용) sed.N\n

[^\n]이로 인해 개행 문자가 아닌 단일 문자와 일치하는 데 사용할 수 있다고 믿게 되었습니다 . 이는 sedGNU 시스템, OpenBSD, FreeBSD 및 Plan 9의 구현에서도 수행됩니다.

답변3

실제로 이 상황을 일반적인 방식으로 처리하는 매우 깔끔한 방법이 있습니다 sed. 개행 문자를 일반 문자(예: _)로 바꾼 다음 [^_]를 수행하고 반환합니다. 원래는 발생한 문제에 대한 해결책을 게시하고 싶었지만 게시하기가 너무 귀찮았지만 지금은 여기에 게시하겠습니다.

sed -e '
   /./!b

   :loop
      $q; N
   /\n$/bloop

   h

   /\ncreate table/!{
      s/\(.*\)\n.*/\1/p
      g;s/.*\(\n\)/\1/;D
   }

   g

   y/\n_/_\n/
      s/^[^_]*/test/
   y/\n_/_\n/

' input.data

위 솔루션에 대한 문제 설명입니다.

답변4

[[:alnum:][:punct:][:blank:]]대괄호 표현식을 사용할 수 있습니다 .

echo "one
two" | sed 'N;s/[[:alnum:][:punct:][:blank:]]/_/g'

산출:

___
___

[:alnum:]모든 영숫자 문자, [:punct:]모든 구두점 및 [:blank:]모든 가로 공백 과 일치합니다 . 모든 세로 공백은 무시되며 일치하지 않습니다.

보다온라인 sed데모.

관련 정보