使用 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不會被修改。

它使用兩個臨時空字元\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

解釋:

使用原始字串中不存在的字元替換要刪除的空格,然後在整個字串中刪除所選字元。\n是一個很好的候選者,因為它不能正常存在,因為它被 sed 用作行分隔符號。

答案4

我最終只是使用 sed 和管道來獲得一個對我來說很容易理解的語句:

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

這一切所做的就是用下劃線替換我不需要的空格,然後刪除它們。感謝所有的答案!

相關內容