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は変更されません。

2 つの一時的な null 文字を使用して\x00行の変更を名前で表示し、スペースを削除します。

:Nそして:S分岐するラベル(どんな名前でも可能)
tで、b分岐コマンドです。
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'

これは、不要なスペースをアンダースコアに置き換えてから削除するだけです。全ての回答ありがとうございます!

関連情報