bash - \x0d\x20が行を削除するのはなぜですか?

bash - \x0d\x20が行を削除するのはなぜですか?

これはgeditエディタの例です: ここに画像の説明を入力してください。

そしてvimエディタの例: ここに画像の説明を入力してください。

その後、Togの代わりにLogを使用するとgrepを試みますが、正常にgrepしますが、出力が破損します。

[xiaobai@xiaobai grep]$ grep  Tog test
[xiaobai@xiaobai grep]$ grep  Log test
                               Dtring.valueOf
[xiaobai@xiaobai grep]$ 

その後、ファイルを見てみると、ファイルも破損しています。

[xiaobai@xiaobai grep]$ cat test 
                               Dtring.valueOf
[xiaobai@xiaobai grep]$ 

だから私は16進ダンプを使います。

[xiaobai@xiaobai grep]$ hexdump -C test 
00000000  4c 6f 67 2e 64 28 22 6d  75 73 69 63 22 2c 20 22  |Log.d("music", "|
00000010  4e 41 56 49 47 41 54 4f  52 3a 20 22 20 2b 20 53  |NAVIGATOR: " + S|
00000020  74 72 69 6e 67 2e 76 61  6c 75 65 4f 66 0d 20 20  |tring.valueOf.  |
00000030  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00000040  20 20 20 20 20 20 20 20  20 20 20 20 20 44 0d 0a  |             D..|
00000050
[xiaobai@xiaobai grep]$ 

私はそれを次のように絞り込んだ。

[xiaobai@xiaobai grep]$ cat test3
                               D
[xiaobai@xiaobai grep]$ hexdump -C test3
00000000  61 0d 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |a.              |
00000010  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00000020  20 44 0d 0a                                       | D..|
00000024
[xiaobai@xiaobai grep]$ echo -e '\x61'
a
[xiaobai@xiaobai grep]$ echo -e '\x61\x0d'
a
[xiaobai@xiaobai grep]$ echo -e '\x61\x0d\x20'

[xiaobai@xiaobai grep]$ echo -e '\x61\x0d\x20\x62'
 b

ご覧のとおり、\x20バイトを追加した後、「a」は削除されます。

だから私の質問はなぜこれが起こり、いくつかのファイルに\ x0d \ x 20(例えばgrep -r )が含まれる可能性があることを事前に知らずに削除する方法です。

答え1

ASCIIコードの文字0〜31は制御文字です。端末に送信されると、特別な操作を実行するために使用されます。たとえば、\a(BEL、0x7)はターミナルベルを鳴らします。\b(BS、0x8)カーソルを後ろに移動します。\n(LF, 0xa) はカーソルを 1 行下に移動し、\t(TAB 0x9) はカーソルを次のテーブルに移動します.

\r(CR, 0xd) カーソルを最初の列に移動します。

端末のシェルプロンプトで実行する場合:

printf 'foo\nbar\n'

printf書き込まれると、デバイスのttyラインルールがそれを変換するため、foo\nbar\n後に次のラインが表示されます。/dev/tty<something>foo\r\nbar\r\nbarfoo

printf 'foo\rbar\n'

foo端末は次のように上書きされますbar

ファイルに制御文字が含まれている場合にその文字を削除するか、その文字があるかどうかを^M確認するには、テキスト表現(CR 0xd文字など)を指定できます。\r

ただし、LFおよびTAB文字についてはこれをしたくありません。だから:

LC_ALL=C tr -d '\0-\10\13-\37\177' < file # to remove them

cat -v < file # to display as ^M

sed -n l < file # to display as \r (also converts TAB to \t)
                # and marks the end of lines with $

これらsedcatそのエントリはASCII以外の文字も変換します。次のことができます。

LC_ALL=C sed "$(printf 's/[^\t -\176\200-\377]/^&/g')" < file |
  LC_ALL=C tr '\0-\10\13-\37\177' '@-HK-_?'

ASCII制御文字(TABおよびLFを除く)のみがビジュアル形式に変換されます^X(ただし、すべての実装がNUL文字を含む入力ファイルをサポートするわけではありませんsed)。

答え2

\x0d\rカーソルを行の先頭に移動してから\x20スペースを取得する文字なので、スペースaで上書きされます。 unix-yシステムを使用している場合は、\rテキスト出力に使用する場合は必要ありません。出力/ファイルから削除することを検討してください。\n* nixでは機能しますが、Windowsでは機能しないことを「暗黙的に」表示します。

関連情報