sed를 사용하여 단일 대문자 뒤의 공백 제거

sed를 사용하여 단일 대문자 뒤의 공백 제거

다른 파일을 자동으로 생성하기 위해 bash 스크립트를 작성 중이며 일부 문자열의 형식을 특정 방식으로 지정해야 합니다. 특히, 제가 겪고 있는 마지막 문제는 개별 대문자가 있는 문자열과 대문자로 시작하는 단어의 형식을 지정하는 것입니다. 예를 들어:

O S D Settings될 필요가OSD Settings

첫 번째 공백을 제거하는 sed 명령이 있지만 "D"도 삭제합니다(예: O S D Settings-> OS Settings). 이 명령은 다음과 같습니다:

O S D Settings | sed 's/ \([A-Z]\)* \(A-Za-z]*\)/\1/g'

글자 하나도 잃지 않고 개별 대문자 사이의 공백을 삭제하는 방법을 아는 사람이 있습니까?

답변1

A B Chadwick이는 다음 과 같은 이름을 처리합니다 .A B C D'Souza

A B cde및 와 같은 텍스트 A B CDE는 수정되지 않습니다.

두 개의 임시 null 문자를 사용하여 \x00한 줄을 따라 진행하면서 변경 사항(이름별)을 표시하고 공백을 제거합니다.

:N그리고 :S분기 대상레이블(어떤 이름이든 가능)
tb분기 지침입니다.
t이전 s/../../명령에서 성공적으로 교체되면 분기됩니다.
b무조건 분기합니다.

sed -r ":N                                                # loop per name
         /(\<[A-Z]\> )+[A-Z][a-z']/{                      # line needs action
             s/((\<[A-Z]\> )+)([A-Z][a-z'])/\x00\1\x00\3/ # add \x00 markers
            :S                                            # loop per space
             s/(\x00[A-Z]+) (\<[A-Z]\>)/\1\2/             # delete a space
             t S                                          # any more spaces? 
             b N                                          # any more names?
         }; s/\x00//g"                                    # remove \x00

답변2

은(는) 까다롭지 sed만 괜찮다면 perl이 방법으로 할 수 있습니다.

echo O S D Settings | perl -p -e 's/(\b[A-Z]) (?=.([^\w]|$))/$1/g'

sed이는 예측 어설션을 지원하지 않기 때문에 어렵습니다 .

테스트:

echo O S D | perl -p -e 's/(\b[A-Z]) (?=.([^\w]|$))/$1/g'
echo O S D Settings | perl -p -e 's/(\b[A-Z]) (?=.([^\w]|$))/$1/g'
echo O S D. | perl -p -e 's/(\b[A-Z]) (?=.([^\w]|$))/$1/g'
echo One O DDE T. S Asdf Q R Tee | perl -p -e 's/(\b[A-Z]) (?=.([^\w]|$))/$1/g'
echo O S D\  | perl -p -e 's/([A-Z]) (?=.([^\w]|$))/$1/g'

을 사용하여 엉성한 솔루션을 원한다면 sed시도해 보십시오.

echo O S D Settings | sed -e 's/ \([A-Z]\) \([A-Z] \)/\1\2/g'

귀하의 샘플에서는 작동하지만 다른 경우에는 실패합니다.

테스트:

echo O S D | sed -e 's/ \([A-Z]\) \([A-Z] \)/\1\2/g'
echo O S D Settings | sed -e 's/ \([A-Z]\) \([A-Z] \)/\1\2/g'
echo O S D. | sed -e 's/ \([A-Z]\) \([A-Z] \)/\1\2/g'
echo One O DDE T. S Asdf Q R Tee | sed -e 's/ \([A-Z]\) \([A-Z] \)/\1\2/g'
echo O S D\  | sed -e 's/ \([A-Z]\) \([A-Z] \)/\1\2/g'

답변3

이것은 당신에게 도움이 될 수 있습니다:

echo "O S D Settings and B T W and A B C D'Souza too F Y I" |
sed ':a;s/\(\<[[:upper:]]\>\) \(\<[[:upper:]]\>\([^'\'']\|$\)\)/\1\n\2/g;ta;s/\n//g'
OSD Settings and BTW and ABC D'Souza too FYI

설명:

원래 문자열에 존재하지 않는 문자를 사용하여 삭제하려는 공백을 대체한 다음 문자열 전체에서 선택한 문자를 삭제합니다. \nsed에서 줄 구분 기호로 사용되기 때문에 정상적으로 존재할 수 없으므로 좋은 후보입니다.

답변4

나는 이해하기 쉬운 명령문을 얻기 위해 파이프와 함께 sed를 사용했습니다.

echo O S D Settings | sed 's/\([A-Z][^ ]\)/_\1/g' | sed 's/ //g' | sed 's/_/ /g'

이 작업은 원하지 않는 공백을 밑줄로 바꾼 다음 삭제하는 것뿐입니다. 모든 답변에 감사드립니다!

관련 정보