sed: 전역적으로 대체할 때 선행 공백을 무시합니다.

sed: 전역적으로 대체할 때 선행 공백을 무시합니다.

파일의 과도한 공백을 대체하기 위해 sed 명령을 작성하려고 합니다. 각 단어 사이에는 공백이 하나만 있어야 하며, 선행 공백과 탭은 그대로 두어야 합니다. 따라서 파일은 다음과 같습니다.

     This is     an indented      paragraph. The   indentation   should not be changed.
This is the     second   line  of the    paragraph. 

될 것입니다:

     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

나는 다양한 변형을 시도했습니다

/^[ \t]*/!s/[ \t]+/ /g

어떤 아이디어라도 감사하겠습니다.

답변1

$ sed 's/\>[[:blank:]]\{1,\}/ /g' file
     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

내가 사용한 표현은 하나 또는 여러 개 [[:blank:]](공백 또는 탭) 와 일치합니다.한마디 후에, 이를 단일 공백으로 바꿉니다. \>단어 문자와 단어가 아닌 문자 사이의 너비가 0인 경계와 일치합니다 .

이것은 OpenBSD의 기본 로 테스트되었지만 sedGNU에서도 작동해야 한다고 생각합니다 sed. GNU는 단어 경계 일치에도 sed사용합니다 .\b

sed -E이것을 다음과 같이 단축하는 데 사용할 수도 있습니다 .

sed -E 's/\>[[:blank:]]+/ /g' file

다시 말하지만, \>GNU에서 작동하지 않으면 대신 sed사용하십시오 \b.


위의 내용은 예제 텍스트를 올바른 방식으로 정렬하지만, 그렇지는 않습니다.상당히첫 번째 문장 이후와 같이 구두점 뒤의 공백을 제거하는 작업

     This is     an indented      paragraph.        The   indentation   should not be changed.
This is the     second   line  of the    paragraph.

이를 위해 약간 더 복잡한 변형이 트릭을 수행합니다.

$ sed -E 's/([^[:blank:]])[[:blank:]]+/\1 /g' file
     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

이는 공백이 아닌 문자 뒤에 하나 이상의 공백 문자가 오는 모든 공백이 아닌 문자와 단일 공백으로 대체됩니다.

또는 표준 sed(그리고 다음이 있는 경우에만 대체를 수행한다는 점에서 매우 작은 최적화)을 사용합니다.둘 이상공백/탭이 아닌 뒤에 공백/탭이 있음),

$ sed 's/\([^[:blank:]]\)[[:blank:]]\{2,\}/\1 /g' file
     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

답변2

POSIX적으로:

sed 's/\([^[:space:]]\)[[:space:]]\{1,\}/\1 /g; s/[[:space:]]*$//'

공백이 아닌 공백 다음에 나오는 하나 이상의 공백 문자 시퀀스를 공백이 아닌 공백과 단일 SPC 문자로 바꾸고, 공백 행과 후행 공백이 있는 행을 덮는 후행 공백 문자를 제거합니다(다음에 있는 CR 포함). Microsoft 텍스트 파일에서 나오는 줄의 끝).

관련 정보