pco*_*rey 348 regex unix unicode grep
我有几个非常大的XML文件,我试图找到包含非ASCII字符的行.我尝试过以下方法:
grep -e "[\x{00FF}-\x{FFFF}]" file.xml
Run Code Online (Sandbox Code Playgroud)
但是这会返回文件中的每一行,无论该行是否包含指定范围内的字符.
我的语法有错吗?或者我做错了什么?我也尝试过:
egrep "[\x{00FF}-\x{FFFF}]" file.xml
Run Code Online (Sandbox Code Playgroud)
(模式周围有单引号和双引号).
jer*_*use 465
您可以使用以下命令:
grep --color='auto' -P -n "[\x80-\xFF]" file.xml
Run Code Online (Sandbox Code Playgroud)
这将为您提供行号,并以红色突出显示非ascii字符.
在某些系统中,根据您的设置,上述操作无效,因此您可以通过反向操作
grep --color='auto' -P -n "[^\x00-\x7F]" file.xml
Run Code Online (Sandbox Code Playgroud)
另请注意,重要的位是-P
等于的标志--perl-regexp
:因此它将您的模式解释为Perl正则表达式.它也说
这是高度实验性的,grep -P可能会警告未实现的功能.
pva*_*erk 119
正如大多数上述解决方案所做的那样,不是对非ASCII字符的字节范围做出假设,而是明确更好地了解ASCII字符的实际字节范围.
所以第一个解决方案将成为:
grep --color='auto' -P -n '[^\x00-\x7F]' file.xml
Run Code Online (Sandbox Code Playgroud)
(基本上对于十六进制ASCII范围之外的任何字符进行greps:从\ x00到\ x7F)
在Mountain Lion上无法工作(由于缺少BSD grep中的PCRE支持),但是pcre
通过Homebrew安装,以下内容也可以正常工作:
pcregrep --color='auto' -n '[^\x00-\x7F]' file.xml
Run Code Online (Sandbox Code Playgroud)
任何人可以想到的任何利弊?
The*_*ema 67
以下适用于我:
grep -P "[\x80-\xFF]" file.xml
Run Code Online (Sandbox Code Playgroud)
非ASCII字符从0x80开始,在查看字节时转到0xFF.Grep(和系列)不进行Unicode处理,将多字节字符合并到单个实体中,以便进行正则表达式匹配.-P
我的grep中的选项允许\xdd
在字符类中使用转义来完成你想要的.
noq*_*ery 51
在perl
perl -ane '{ if(m/[[:^ascii:]]/) { print } }' fileName > newFile
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 41
简单的方法是将非ASCII字符定义为不是ASCII字符的字符.
LC_ALL=C grep '[^ -~]' file.xml
Run Code Online (Sandbox Code Playgroud)
^
如有必要,请在添加选项卡后添加.
设置LC_COLLATE=C
避免了许多语言环境中关于字符范围含义的令人讨厌的意外.设置LC_CTYPE=C
是匹配单字节字符所必需的 - 否则命令将错过当前编码中的无效字节序列.设置LC_ALL=C
完全避免了与语言环境相关的影响.
rya*_*anm 24
这是我发现的另一个变体,它在接受的答案中产生了与grep搜索完全不同的结果[\x80-\xFF]
.也许有人找到额外的非ascii字符会很有用:
grep --color='auto' -P -n "[^[:ascii:]]" myfile.txt
注意:我的计算机的grep(Mac)没有-P
选项,所以我做了brew install grep
并开始上面的调用ggrep
而不是grep
.
小智 9
以下代码有效:
find /tmp | perl -ne 'print if /[^[:ascii:]]/'
Run Code Online (Sandbox Code Playgroud)
替换/tmp
为要搜索的目录的名称.
搜索不可打印的字符。TLDR;执行摘要
搜索控制字符和扩展的unicode
语言环境设置,例如LC_ALL = C,以使grep执行扩展的unicode所期望的操作
因此,首选的非ascii字符查找器:
$ perl -ne'打印“ $。$ _”如果m / [\ x00- \ x08 \ x0E- \ x1F \ x80- \ xFF] /'notes_unicode_emoji_test
如最佳答案中所示,逆grep:
$ grep --color ='auto'-P -n“ [^ \ x00- \ x7F]” notes_unicode_emoji_test
如最佳答案中所示,但WITH LC_ALL = C:
$ LC_ALL = C grep --color ='auto'-P -n“ [\ x80- \ xFF]” notes_unicode_emoji_test
。。更多 。。令人毛骨悚然的细节:。。
我同意上面隐藏在注释中的Harvey的观点,搜索不可打印的字符通常更有用,或者当您真的应该考虑不可打印的字符时,很容易想到非ASCII。Harvey建议“使用此:“ [^ \ n-〜]”。为DOS文本文件添加\ r。这将转换为“ [^ \ x0A \ x020- \ x07E]”,并为CR添加\ x0D”
另外,在搜索不可打印的字符时,向grep添加-c(显示匹配模式的计数)非常有用,因为匹配的字符串可能会使终端混乱。
我发现将范围0-8和0x0e-0x1f(添加到0x80-0xff范围)是一个有用的模式。这不包括TAB,CR和LF以及一个或两个以上不常见的可打印字符。因此,恕我直言,一个非常有用的(尽管是粗糙的)grep模式是这样的:
grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" *
Run Code Online (Sandbox Code Playgroud)
实际上,通常您需要执行以下操作:
LC_ALL=C grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" *
Run Code Online (Sandbox Code Playgroud)
分解:
LC_ALL=C - set locale to C, otherwise many extended chars will not match (even though they look like they are encoded > 0x80)
\x00-\x08 - non-printable control chars 0 - 7 decimal
\x0E-\x1F - more non-printable control chars 14 - 31 decimal
\x80-1xFF - non-printable chars > 128 decimal
-c - print count of matching lines instead of lines
-P - perl style regexps
Instead of -c you may prefer to use -n (and optionally -b) or -l
-n, --line-number
-b, --byte-offset
-l, --files-with-matches
Run Code Online (Sandbox Code Playgroud)
例如,使用find的实际示例grep grep当前目录下的所有文件:
LC_ALL=C find . -type f -exec grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" {} +
Run Code Online (Sandbox Code Playgroud)
您可能希望有时调整grep。例如,在某些可打印文件中使用的BS(0x08-退格键)字符或排除VT(0x0B-垂直制表符)。在某些情况下,BEL(0x07)和ESC(0x1B)字符也可以视为可打印的。
Run Code Online (Sandbox Code Playgroud)Non-Printable ASCII Chars ** marks PRINTABLE but CONTROL chars that is useful to exclude sometimes Dec Hex Ctrl Char description Dec Hex Ctrl Char description 0 00 ^@ NULL 16 10 ^P DATA LINK ESCAPE (DLE) 1 01 ^A START OF HEADING (SOH) 17 11 ^Q DEVICE CONTROL 1 (DC1) 2 02 ^B START OF TEXT (STX) 18 12 ^R DEVICE CONTROL 2 (DC2) 3 03 ^C END OF TEXT (ETX) 19 13 ^S DEVICE CONTROL 3 (DC3) 4 04 ^D END OF TRANSMISSION (EOT) 20 14 ^T DEVICE CONTROL 4 (DC4) 5 05 ^E END OF QUERY (ENQ) 21 15 ^U NEGATIVE ACKNOWLEDGEMENT (NAK) 6 06 ^F ACKNOWLEDGE (ACK) 22 16 ^V SYNCHRONIZE (SYN) 7 07 ^G BEEP (BEL) 23 17 ^W END OF TRANSMISSION BLOCK (ETB) 8 08 ^H BACKSPACE (BS)** 24 18 ^X CANCEL (CAN) 9 09 ^I HORIZONTAL TAB (HT)** 25 19 ^Y END OF MEDIUM (EM) 10 0A ^J LINE FEED (LF)** 26 1A ^Z SUBSTITUTE (SUB) 11 0B ^K VERTICAL TAB (VT)** 27 1B ^[ ESCAPE (ESC) 12 0C ^L FF (FORM FEED)** 28 1C ^\ FILE SEPARATOR (FS) RIGHT ARROW 13 0D ^M CR (CARRIAGE RETURN)** 29 1D ^] GROUP SEPARATOR (GS) LEFT ARROW 14 0E ^N SO (SHIFT OUT) 30 1E ^^ RECORD SEPARATOR (RS) UP ARROW 15 0F ^O SI (SHIFT IN) 31 1F ^_ UNIT SEPARATOR (US) DOWN ARROW
更新:我最近不得不重新审视它。并且,YYMV取决于终端设置/太阳能天气预报BUT。。我注意到grep找不到很多unicode或扩展字符。即使从直觉上来说,它们应该匹配0x80到0xff的范围,但3和4字节的unicode字符却不匹配。??? 谁能解释一下?是。@frabjous询问和@calandoa解释说,应使用LC_ALL = C来设置命令的语言环境以使grep匹配。
例如我的语言环境LC_ALL =空
$ locale
LANG=en_IE.UTF-8
LC_CTYPE="en_IE.UTF-8"
.
.
LC_ALL=
Run Code Online (Sandbox Code Playgroud)
带有LC_ALL =空的grep匹配2字节编码的字符,但不匹配3和4字节编码的字符:
$ grep -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" notes_unicode_emoji_test
5:© copyright c2a9
7:call underscore c2a0
9:CTRL
31:5 © copyright
32:7 call underscore
Run Code Online (Sandbox Code Playgroud)
具有LC_ALL = C的grep似乎与您想要的所有扩展字符匹配:
$ LC_ALL=C grep --color='auto' -P -n "[\x80-\xFF]" notes_unicode_emoji_test
1:???? unicode dashes e28090
3:??? Heart With Arrow Emoji - Emojipedia == UTF8? f09f9298
5:? copyright c2a9
7:call? underscore c2a0
11:LIVE??E! ?????????? ???? ?????????? ???? ?? ?? ???? ???? YEOW, mix of japanese and chars from other e38182 e38184 . . e0a487
29:1 ???? unicode dashes
30:3 ??? Heart With Arrow Emoji - Emojipedia == UTF8 e28090
31:5 ? copyright
32:7 call? underscore
33:11 LIVE??E! ?????????? ???? ?????????? ???? ?? ?? ???? ???? YEOW, mix of japanese and chars from other
34:52 LIVE??E! ?????????? ???? ?????????? ???? ?? ?? ???? ???? YEOW, mix of japanese and chars from other
81:LIVE??E! ?????????? ???? ?????????? ???? ?? ?? ???? ???? YEOW, mix of japanese and chars from other
Run Code Online (Sandbox Code Playgroud)
这个perl匹配项(部分在stackoverflow上的其他地方找到)或最上面答案的反grep似乎确实找到了所有〜weird〜和〜wonderful〜“ non-ascii”字符而未设置语言环境:
$ grep --color='auto' -P -n "[^\x00-\x7F]" notes_unicode_emoji_test
$ perl -ne 'print "$. $_" if m/[\x00-\x08\x0E-\x1F\x80-\xFF]/' notes_unicode_emoji_test
1 ?? unicode dashes e28090
3 Heart With Arrow Emoji - Emojipedia == UTF8? f09f9298
5 © copyright c2a9
7 call underscore c2a0
9 CTRL-H CHARS URK URK URK
11 LIVE?E! ????? ?? ????? ?? ? ? ?? ?? YEOW, mix of japanese and chars from other e38182 e38184 . . e0a487
29 1 ?? unicode dashes
30 3 Heart With Arrow Emoji - Emojipedia == UTF8 e28090
31 5 © copyright
32 7 call underscore
33 11 LIVE?E! ????? ?? ????? ?? ? ? ?? ?? YEOW, mix of japanese and chars from other
34 52 LIVE?E! ????? ?? ????? ?? ? ? ?? ?? YEOW, mix of japanese and chars from other
73 LIVE?E! ????? ?? ????? ?? ? ? ?? ?? YEOW, mix of japanese and chars from other
Run Code Online (Sandbox Code Playgroud)
因此,首选的非ascii字符查找器:
$ perl -ne'打印“ $。$ _”如果m / [\ x00- \ x08 \ x0E- \ x1F \ x80- \ xFF] /'notes_unicode_emoji_test
如最佳答案中所示,逆grep:
$ grep --color ='auto'-P -n“ [^ \ x00- \ x7F]” notes_unicode_emoji_test
如最佳答案中所示,但WITH LC_ALL = C:
$ LC_ALL = C grep --color ='auto'-P -n“ [\ x80- \ xFF]” notes_unicode_emoji_test
归档时间: |
|
查看次数: |
245066 次 |
最近记录: |