この質問の単語が「文字間隔」であるかのように、いくつかの単語が文字間隔で配置されたいくつかのテキストを含むソーステキストファイルがあります(つまり、単語文字の間にスペース文字があります)。
sedを使用して文字間隔を削除するには?
このようなパターンは、\{[A-Za-z] \}+[A-Za-z]
文字間隔の単語をキャプチャし、s/ //g
スペースを削除します。しかし、テキスト行から文字間隔単語を抽出し、残りのテキストの正しい空白文字を損なうことなく文字間隔を取り消すにはどうすればよいですか?
答え1
次のことができます。
sed -e's/ \([^ ][^ ]\)/\n\1/g' \
-e's/\([^ ][^ ]\) /\1\n/g' \
-e's/ //g;y/\n/ /
' <<\IN
I have a source text file containing text where
some words are l e t t e r s p a c e d
like the word "letterspaced" in this question
(i.e., there is a space character between the
letters of the word.
IN
アイデアは、最初に2つ以上の空白以外の文字が前後のすべての空白を見つけ、改行文字として別々に設定することです。次に、残りの空白をすべて削除します。最後に、改行文字をすべて空白に変換します。
完璧ではありません。すべての単語を含む完全な辞書がない場合は、一種の経験的な方法を使用するのが最善です。しかし、これは大丈夫です。
また、使用している項目によっては、sed
リテラル改行文字を代わりに使用する必要があります。n
私は最初の2つの交換ドアにも使用しています。
ただし、この注意事項に加えて、これはすべてのPOSIXで機能し、非常に迅速に機能しますsed
。不可能なケースを保存するため、高価な順方向または逆方向の操作を実行する必要はありません。これは、単一アドレスのすべての置換のすべてのパターンスペースを処理できることを意味します。
出力
I have a source text file containing text where some
words are letterspaced
like the word "letterspaced" in this question
(i.e., there is a space character between the
letters of the word.
答え2
最も効率的なPerlメソッド:
perl -C -lpe 's/(?:^|\P{L})\K\p{L}(?:\s\p{L})+(?=\P{L}|$)/$&=~s{\s}{}rgo/goe'
/r
これは、あなたのPerlバージョンが置き換えられるフラグを理解するのに十分な新しいバージョンであると仮定します。
概念の証拠:
$ echo 'Do I like «ł é t t ê r s p ä c è đ» text?' | perl -C -lpe 's/(?:^|\P{L})\K\p{L}(?:\s\p{L})+(?=\P{L}|$)/$&=~s{\s}{}rgo/goe'
Do I like «łéttêrspäcèđ» text?
答え3
Perlの予測宣言を使用すると、これを簡単に実行できます。 AFAIK、sedにはこれが足りません。
複数のスペースが単語を区切る場合、単一のスペースは削除されますが、複数のシーケンスは変更されません。
perl -pe 's/\s(?!\s)//g' myfile
このp
スイッチを使用すると、Perlは後ろに他のスペースが来ない単一のスペース()を読み取ってmyfile
交換します。\s
これは与えられた否定的な予測主張です(?!\s)
。