ターミナル出力に単位区切り記号(ASCII 31)が表示されないのはなぜですか?

ターミナル出力に単位区切り記号(ASCII 31)が表示されないのはなぜですか?

単位区切り記号ASCII文字(ASCII 31、8進数37)はVimから^_。これにより、行のフィールドが互いにくっつきます。

# In Vim and less:

first field^_second field^_last field

# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field

# print 2nd field with awk 
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field

単位区切り記号を表示するには、cat -vを使用できると思います。

cat -v delim.txt
first field^_second field^_last field

ところがこれがもっと問題だ。 Bashシェルからstdoutとして印刷するときに単位区切り記号に目に見える表現がないのはなぜですか?シェル出力を正しくコピーして貼り付けることもできません。単位区切り記号がプロセスから失われます。

答え1

USとも呼ばれる単位区切り文字()文字は文字クラスにIS1属し、次のようになります。cntrlいいえprintキャラクタークラスです。テキストをグループ化するために使用される制御文字であり、この情報を活用するように設計されたプログラムの場合。通常、印刷できない文字は、プログラムや環境によって異なるように解釈されレンダリングされることがあります。

Vimで表示される理由は、^_Vimがインタラクティブエディタであるためです。正しいバイナリ文字がディスクに書き込まれる限り、印刷できない文字を自由にレンダリングできます。

Unixシェルプログラムはプレーンテキストを操作し、プレーンテキストを互いに渡すように書かれているため、シェルは同じ動作を取得できません。ファイルを生成するときにcat端末に書き込まれるテキストは、ファイルの実際の内容でなければなりません。

これは、文字の解釈を最終デバイスに任せます。一部の端末エミュレータはするUS他のキャラクターと差別化されたキャラクターを作ってみてください。 (gnome-terminalまたはvteそれに基づくすべての端末)文字は、16進コードを含むボックスとしてレンダリングされます001Fxtermまたは ではrxvt文字が実際には見えません。

答え2

単位区切り記号のASCII範囲は次のとおりです。制御文字したがって、視覚的表現がないか、一般的には存在しないはずです。

Vimと他の編集者は編集できるようにそれを表示します。気づいたようにcat -vそれも現れます。マニュアルページでは、これは印刷できない文字をファイルの元の内容ではなく印刷可能な表現に置き換えるという短縮形式であることを-v示しているため、出力が実際に別のプログラムから出てくると問題が発生する可能性があります。--show-nonprinting

あなたが見る表現はすでに制御文字であることを示唆しています。 a先行する文字は、端末でその文字を生成するキーの組み合わせである+文字の一般的な表現^です。Ctrlたとえば、Ctrl+を使用すると、vimに単位区切り文字を入力できます。_ただし、他のエディタや一部のGUIビューアには、16進コード、プレースホルダ、またはまったく異なるコンテンツが表示されることがあります。

端末は制御文字を印刷しないため、テキストを選択するとコピーされません(改行やタブなどの空白文字はここでは例外であり、制御文字でもあります)。コピー時に無視される端末制御文字のもう1つの例は、カラーコードです。カラーコードは、ESC文字の後にテキストの色を指定するために使用されるコードです。

したがって、端末に文字を表示するには、単位区切り文字を印刷可能な文字に置き換えるプログラムを使用する以外に、他の方法はありません。

答え3

変更したい場合は、他の(非常に良い)答えの端に少しただファイルの内容を表示するときに制御文字を使用することをお勧め^_します。音域trユーティリティ(およびいくつかのbash互換構文)を使用してください。

# Replace the control character US (^_) by *one* other character
$ cat my.file | tr $'\c_' ':'

対応する制御文字を「拡張」形式に置き換えるには、次のものが必要ですsed

# Replace the control character US (^_) by any string
cat /tmp/f | sed s/$'\c_'/^_/g

構文に注意してください$'\cX'。この構文は、(bash互換シェル)に適切な制御文字を置き換えるように指示します。バラよりWikipediaの制御文字エイリアスリスト「カラット」を使用してください。この構文が気に入らない場合は、8進数$'\037'または16進$'\x1f'表記を使用することをお勧めします。

関連情報