2016-11-25 501 views
1

因此,當幫助某人調試某些代碼時,我意識到他們的輸出中有一些奇怪的字符,即 和 (十六進制中的\ xc0和\ xd0)。如何使用十六進制表示grep特殊字符(控制字符)

我想在一個大的文本輸出文件中找到這些字符。

我設法找到這些字符使用崇高找到正則表達式選項查找與\xc0\xd0查詢。我也通過在bash中執行grep $'\xc0' filename來設法達到grep

現在困擾我的是,如果我使用-P選項grep,它拒絕找到這些字符。

grep -P "\xc0" filename將打印出沒有任何文件,其中有該字符(和上面的其他兩種方法可以成功找到它),這是在煩擾我如此糟糕,我想知道爲什麼這不起作用。

我看過一對夫婦的其他職位,其中有"[\x80-\xff]"沿-P選項的建議,但由於某種原因,我不能讓他們的工作:\

grep -P一直是很好的朋友了很久時間到現在爲止:(任何幫助和提示是讚賞

我使用GNU grep的

編輯:!

我公頃實際上我已經嘗試了2個Linux發行版。

  • 在Ubuntu 14.04使用bash:我的終端似乎並不喜歡這個角色:\

printf "\xc0"打印出沒有在終端,但它打印到文件與>,然後在打開崇高將顯示角色。

printf "\xc0" > foo 
grep $'\xc0' foo > out1 
grep -P '\xc0' foo > out2 
grep -P '\x{c0}' foo > out3 

out{1,2,3}都是空的。

  • 在CentOS 7.2使用bash:printf打印的東西 - 問號黑暗啄

printf "\xc0"打印出來(其實是這樣的)

printf "\xc0" > foo 
grep $'\xc0' foo > out1 
grep -P '\xc0' foo > out2 
grep -P '\x{c0}' foo > out3 

只有out1包含字符。

+0

我可能聽起來很生氣,不願意在原文中學習,但我很想學習:)可能有一些與'grep -P'有關的警告我不知道,我會很樂意找到了解它:) – a283626086

+0

'我只是無法讓他們工作'?你看到了什麼錯誤? – Inian

+0

你試過'grep -P「\ x {c0}」文件名「嗎?甚至是「\ x {00c0}」'? –

回答

0

字節

你需要做的第一件事就是給一個變量,你要搜索的確切字節內創建。

事情是任何這樣的:

a=$(echo -e '\xc0) 
a=$'\xc0' 
a=$(printf '\xc0') 
a=$(echo -e '\300')  # 300 is 0xC0 in octal 
a=$'\300' 
a=$(printf '\300') 
a=$(echo "c0" | xxd -r -p) 

我可以嘗試想出一些其他的方式,但我希望你的想法。

然後,你可以嘗試搜索byte使用grep:

echo $'Testing this: \xC0 byte' | grep "$a" 

而且,如果您使用UTF-8語言環境(這是最常見的),這將失敗。 如果您更改爲ISO-8859-1語言環境,將工作:

LC_ALL=en_US.iso88591 echo $'Testing this: \xC0 byte' | 
LC_ALL=en_US.iso88591 grep -P "$a" 

或者,如果你不介意啓動一個新的bash實例:

$ bash 
$ export LC_ALL=en_US.iso88591 
$ echo $'Testing this: \xC0 byte' | grep -P "$a" 

而剛剛回歸通過執行exit執行舊的bash環境。
這可能工作或不工作取決於您的系統。

讓我們來探索另一面:角色。

character

有一個非常非常重要的轉折,你應該明白。
一個字節不是一個字符。那麼,有時候,幸運的是,它是。

但是除了128個ASCII字符(其中一個字節是一個字符(不是UTF-16或UTF-32,我們也忘記了EBCDIC))之外,所有1,114,112(17×65,536)個UNICODE編碼點都有多個字節1

在這種情況下,您應該要求UNICODE代碼點的十六進制數0xC0
在現代慶典,就像這樣:

$ printf '\U00C0` 
À 

這是this character: LATIN CAPITAL LETTER A WITH GRAVE

如果語言環境是ISO-8859-1將被編碼爲一個字節(和ISO-8859-15,至少)如果語言環境是utf-8,則爲兩個字節。

$ a=$(printf '\UC0') 
$ printf 'Testing \U00C0 character' | grep -P "$a" 
Testing À character 

如果您更改LC_ALL變量,它也會工作。那麼,我的意思是說,grep會檢測字符,但是由於改變的語言環境,打印的行可能無法正確呈現字符。

如果該文件有這個字符並且該文件的編碼是正確的。 Grep將使用變量中字符的值。

+0

非常感謝你的解釋!我總是與字符編碼和所有這些混淆。在我的Ubuntu機器上'printf'\ U00c0''的確將這個字符打印到我的終端上。所以'printf'\ xc0''不顯示是因爲shell的語言環境(如果我打印到文件中,我能夠看到它在崇高中)? – a283626086

+0

我感到困惑的主要原因之一是我可以使用'\ xc0'正則表達式搜索sublime中的字符,而我似乎無法使用'grep'的'-P'選項來進行搜索,如我在其他許多帖子中看到的,例如[this one](http://stackoverflow.com/questions/23695609/how-to-grep-for-presence-of-specific-hex-bytes-in-files )和[this one](http://unix.stackexchange.com/questions/19491/how-to-specify-characters-using-hexadecimal-codes-in-grep)。 – a283626086

+0

@ a283626086你可以在崇高中使用'\ xc0',因爲它假設**是一個特定的代碼頁(只有256個字符),可能是ISO-8859-1(在美國)或ISO-8859-5(在俄羅斯)或ISO-8859-7(希臘)。在那個有限的字符集中,字節C0表示特定的字符,或者(分別針對上面的代碼頁)。但是這也意味着當代碼頁被改變時所使用的字符可能會改變。崇高選擇一個字符集只是它的一個限制。 UTF-8打破了這個限制。擁抱UTF-8並可自由編寫任何角色。 – sorontar

相關問題