[英]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+2013
( 0xe2
, 0x80
, 0x93
)不是通過作為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.