Bash
bash - 為什麼 x0dx20 刪除該行
這是來自 gedit 編輯器的視圖:
以及來自 vim 編輯器的視圖:
然後我嘗試 grep 它,如果我輸入 Log 而不是 Tog,它會成功 grep,但輸出已損壞:
[xiaobai@xiaobai grep]$ grep Tog test [xiaobai@xiaobai grep]$ grep Log test Dtring.valueOf [xiaobai@xiaobai grep]$
然後我 cat 文件,它也已損壞:
[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 字節後,‘a’ 被刪除了。
所以我的問題是,為什麼會發生這種情況?如果事先不知道某些文件可能包含 \x0d\x20,例如 grep -r,我如何才能擺脫這種情況?
ASCII 中程式碼 0 到 31 的字元是控製字元。當發送到終端時,它們習慣於做特殊的事情。例如,
\a
(BEL, 0x7) 敲響終端的鈴聲。\b
(BS, 0x8) 向後移動游標。\n
(LF, 0xa) 將游標向下移動一行,\t
(TAB 0x9) 將游標移動到下一個列表…
\r
(CR, 0xd) 將游標移動到第一列。當您在終端的 shell 提示符下執行時:
printf 'foo\nbar\n'
printf
寫入foo\nbar\n
到/dev/tty<something>
,該設備的 tty 線路規程將其轉換為foo\r\nbar\r\n
,這就是為什麼您bar
在之後的下一行看到的原因foo
。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 $
請注意,這些
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 字元的輸入文件)。