web-dev-qa-db-ja.com

bash- \ x0d \ x20が行を消去するのはなぜですか

これはgeditエディターからのビューです: enter image description here

とvimエディターからのビュー: enter image description here

次に、grepを試みます。Togの代わりにLogを配置すると、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]$ 

だから私はhexdumpを使用します:

[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バイトを1バイト追加すると「a」が消去されます。

だから私の質問は、なぜそれが起こっているのか、そしていくつかのファイルの事前の知識なしにこれを取り除くにはどうすればいいですか?例えば、\ x0d\x20が含まれている可能性があります。 grep -r?

6
林果皞

ASCIIのコード0〜31の文字は制御文字です。端末に送信されると、特別なことを行うために使用されます。たとえば、\a(BEL、0x7)が鳴ります端末のベル。\b(BS、0x8)はカーソルを後方に移動します。\n(LF、0xa)はカーソルを1行下に移動し、\t(TAB 0x9)はカーソルを次の集計...

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

ターミナルのシェルプロンプトで実行する場合:

printf 'foo\nbar\n'

printffoo\nbar\n/dev/tty<something>に書き込み、そのデバイスのtty行の規律はそれをfoo\r\nbar\r\nに変換します。そのため、次の行にbarが表示されます。 fooの後。

printf 'foo\rbar\n'

ターミナルはfoobarで上書きします。

ファイルに制御文字が含まれている場合は、それらを削除するか、存在を確認する場合はテキスト表現(たとえば、CR0xd文字の場合は^Mまたは\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 $

これらのsedおよびcatは、非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視覚形式に変換するには(ただし、すべてのsed実装がNUL文字を含む入力ファイルをサポートしているわけではないことに注意してください)それらの中で)。

14

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

4
Eric Renouf