簡體   English   中英

搜索非ascii字符

[英]Searching for non-ascii characters

我有一個文件,a.out,其中包含許多行。 每行只有一個字符,可以是unicode字符U+2013或小寫字母az

在a.out上執行文件命令會引發結果UTF-8 Unicode文本。

locale命令報告:

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

如果我發出命令grep -P -n "[^\\x00-\\xFF]" a.out我希望只返回包含U+2013的行。 如果我在cygwin下進行測試就是這種情況。 然而,問題環境是Oracle Linux Server 6.5版,問題是grep命令不返回任何行。 如果我發出grep -P -n "[\\x00-\\xFF] ”a.out,則返回所有行。

我意識到“ [grep -P] ......是高度實驗性的, grep -P可能會警告未實現的功能。” 但沒有發出警告。

我錯過了什么嗎?

我建議避免使用狡猾的grep -P實現並使用真實的東西。 這有效:

perl -CSD -nle 'print "$.: $_" if /\P{ASCII}/' utfile1 utfile2 utfile3 ...

哪里:

  • -CSD選項表示stdio trio(stdin,stdout,stderr)和磁盤文件都應該被視為UTF-8編碼。

  • $. 代表當前記錄(行)編號。

  • $_代表當前行。

  • \\P{ASCII}匹配任何 ASCII的代碼點。

我如何grep中的注釋對於UNIX中的所有非ASCII字符給出了答案:

Grep(和系列)不進行Unicode處理,將多字節字符合並到單個實體中,以便進行正則表達式匹配。

這意味着,UTF-8編碼U+20130xe20x800x93 )不是通過作為grep的給定范圍之外的單個打印字符的部分進行處理。

GNU grep手冊-P沒有提到Unicode或UTF-8。 相反,它說將模式解釋為Perl正則表達式。 (這並不意味着結果 Perl 相同 ,只是一些反斜杠轉義類似 )。

可以告訴 Perl本身使用UTF-8編碼。 但是,在過濾無效的utf8中使用Perl的示例不使用該功能。 相反,表達式(如有問題的grep中的表達式)僅測試單個字節 - 而不是完整字符。

gawk可以幫助你解決這個問題,

這是awk單行:

 awk -v FS="" 'BEGIN{for(i=1;i<128;i++)ord[sprintf("%c",i)]=i}
               {for(i=1;i<=NF;i++)if(!($i in ord))print $i}' file

以下是gawk的測試:

kent$  cat f
abcd
+ß
s+äö
ö--我
中文

kent$  awk -v FS="" 'BEGIN{for(i=1;i<128;i++)ord[sprintf("%c",i)]=i}{for(i=1;i<=NF;i++)if(!($i in ord))print $i}' f
ß
ä
ö
ö
我
中
文

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM