POSIX sedを使用して印刷できない文字を削除する

POSIX sedを使用して印刷できない文字を削除する

roff他の「古い」ツール(たとえば、多くのUnixシステムのマニュアルページ)を使用して生成されたファイルは、太字のテキストを取得する^Hために印刷できないASCII文字(「半バックスペース」など)に関連するトリックを使用したミニマリスト端末です。で太字と下線付きのテキストを生成します。下線付きのテキスト。例:

b^Hbo^Hol^Hld^Hd and _^Hu_^Hn_^Hd_^He_^Hr_^Hl_^Hi_^Hn_^He_^Hd

bold and underline人間が読めるプレーンテキスト(形式を無視)に変換するには、vim次のようなものを使用できます:%s:\(.\)\b\1:\1:ge | %s:_\b\(.\):\1:ge

また、テキストをパイプしtr -dcてPerlの正規表現魔法を使用して、完全に繰り返される文字ペアで構成される単語を見つけることもできます。

sedただし、これは一般的なタスクが処理できる必要があるように見えるため、スクリプトでよりきれいに使用できます。

質問:この翻訳は大丈夫ですか?ただPOSIXを使用していますかsed?つまり、GNUまたはBSD拡張を使用しませんか?

^Hここで問題を引き起こすのは、印刷できない文字(ASCII#8)です。 Bruce Barnettの本にはトリックが言及されています。Sed - はじめにしかし、なんとか動作させることはできません。

ベストアンサー1

あなたはこれができますか?ただPOSIXを使用していますかsed?例:

sed -e 's/.^H//g' < data

これは^H文字通りのバックスペース文字です。 POSIXsedの使用POSIX基本正規表現、バイトで定義されます。文字が印刷されるかどうかにかかわらず、^H文字と同じように動作します。これには拡張は含まれません。実際に必要なのはバックスペース文字を削除することであるため、例のキャプチャグループは実際には必要ありません。

ほとんどの場合、バックスペース文字を入力できますCtrl+V Ctrl+H

あなたの基本的な質問は、「シェルスクリプトでこれをどのように実行しますか?」と思います。文字通りのバックスペース文字は不快かもしれません(もちろん喜んでvim同じことを受け入れるかもしれませんCtrl+V Ctrl+H)。これがあなたのリンクの紹介ですtr

POSIXtrサポートする様々な種類エスケープ文字\b、バックスペース文字の記号エスケープが含まれています。バックスペース文字を変数に保存し、その変数をsed上記の式に置き換えることができます。

BACKSPACE=$(echo x | tr 'x' '\b')
sed -e "s/.$BACKSPACE//g" < data

tr私たちは単にanをバックスペース文字に置き換え、単一の文字を入力として提供するように指示します。これは、Solarisを含む私がアクセスできるすべてのシステムでうまく機能します。しかし、xxprintfPOSIXで定義したツールでもあります。で、同じエスケープをサポートします。

BACKSPACE=$(printf '\b')
sed -e "s/.$BACKSPACE//g" < data

これはtrバージョンよりもシンプルでシンプルです。sed変数の補間を抑制しないように、式の周りに二重引用符を書き留めてください。また、使用することができますコマンドの置き換えprintf '\b'一度だけ使用したい場合は、変数を使用するのではなく、インラインで直接配置できます。

hexdumpこれが(または)に適用されることを確認できますhd

$ dash
$ hexdump -C data
00000000  62 08 62 6f 08 6f 6c 08  6c 64 08 64 0a           |b.bo.ol.ld.d.|
$ BACKSPACE=$(printf '\b')
$ sed -e "s/.$BACKSPACE//g" < data | hexdump -C
00000000  62 6f 6c 64 0a                                    |bold.|

必要に応じて、バックスペース文字と削除された先行文字が出力から削除されます(0a終了文字)。

おすすめ記事