Как я могу grep для всех символов, отличных от ASCII?



у меня есть несколько очень больших XML-файлов, и я пытаюсь найти строки, содержащие символы, отличные от ASCII. Я пробовал следующее:



grep -e "[x{00FF}-x{FFFF}]" file.xml


но это возвращает каждую строку в файле, независимо от того, содержит ли строка символ в указанном диапазоне.



у меня неправильный синтаксис или я делаю что-то еще не так? Я тоже пробовал:



egrep "[x{00FF}-x{FFFF}]" file.xml 


(с одинарными и двойными кавычками, окружающими шаблон).

671   10  

10 ответов:

вы можете использовать команду:

grep --color='auto' -P -n "[\x80-\xFF]" file.xml

это даст вам номер строки и выделит символы, отличные от ascii, красным цветом.

в некоторых системах, в зависимости от ваших настроек, выше не будет работать, так что вы можете grep по обратной

grep --color='auto' -P -n "[^\x00-\x7F]" file.xml

Отметим также, что важным элементом является тег -P флаг, который составляет --perl-regexp: Так он будет интерпретировать ваш шаблон как регулярное выражение Perl. Он также говорит, что

это сильно экспериментальный и grep-P может предупредить о нереализованном особенности.

вместо того, чтобы делать предположения о диапазоне байтов символов, отличных от ASCII, как это делают большинство вышеприведенных решений, немного лучше IMO быть явным о фактическом диапазоне байтов символов ASCII.

Так что первое решение, например, станет:

grep --color='auto' -P -n '[^\x00-\x7F]' file.xml

(который в основном greps для любого символа за пределами шестнадцатеричного диапазона ASCII: от \x00 до \x7F)

на горном Льве это не сработает (из-за отсутствие поддержки PCRE в BSD grep), но с pcre установленный через Homebrew, следующее будет работать так же хорошо:

pcregrep --color='auto' -n '[^\x00-\x7F]' file.xml

любые плюсы или минусы, которые кто-нибудь может придумать?

следующие работы для меня:

grep -P "[\x80-\xFF]" file.xml

символы, отличные от ASCII, начинаются с 0x80 и переходят к 0xFF при просмотре байтов. Grep (и семейство) не выполняют обработку Unicode для объединения многобайтовых символов в одну сущность для сопоставления регулярных выражений, как вам кажется. Элемент -P опция в моем grep позволяет использовать \xdd экранирует в классах символов, чтобы выполнить то, что вы хотите.

в perl

perl -ane '{ if(m/[[:^ascii:]]/) { print  } }' fileName > newFile

простой способ-определить символ, отличный от ASCII... как символ, который не является символом ASCII.

LC_ALL=C grep '[^ -~]' file.xml

Добавить вкладку после ^ при необходимости.

задание LC_COLLATE=C позволяет избежать неприятных сюрпризов о значении диапазонов символов во многих регионах. Установка LC_CTYPE=C необходимо сопоставить однобайтовые символы-в противном случае команда пропустит недопустимые последовательности байтов в текущей кодировке. Установка LC_ALL=C позволяет избежать эффектов, зависящих от локали в целом.

вот еще один вариант, который я нашел, что произвел полностью различные результаты поиска grep для [\x80-\xFF] в принятом ответе. Возможно, кому-то будет полезно найти дополнительные не-ascii символы:

grep --color='auto' -P -n "[^[:ascii:]]" myfile.txt

Примечание: grep моего компьютера (Mac) не было , Так что я сделал brew install grep и начал вызов выше с ggrep вместо grep.

следующий код работает:

find /tmp | perl -ne 'print if /[^[:ascii:]]/'

заменить /tmp С именем каталога, в котором вы хотите выполнить поиск.

странно, я должен был сделать это сегодня! Я закончил использовать Perl, потому что я не мог заставить grep/egrep работать (даже в режиме-P). Что-то вроде:

cat blah | perl -en '/\xCA\xFE\xBA\xBE/ && print "found"'

для символов Unicode (например,\u2212 в примере ниже) использовать это:

find . ... -exec perl -CA -e '$ARGV = @ARGV[0]; open IN, $ARGV; binmode(IN, ":utf8"); binmode(STDOUT, ":utf8"); while (<IN>) { next unless /\N{U+2212}/; print "$ARGV: $&: $_"; exit }' '{}' \;

Поиск непечатаемых символов.

Я согласен с Харви выше похоронен в комментариях, это часто более полезно для поиска непечатаемых символов или легко думать не ASCII, когда вы действительно должны думать непечатаемые. Харви предлагает "использовать это:" [^\n -~]". Добавить \r для текстовых файлов DOS. Что переводится как " [^\x0A\x020 - \x07E]" и добавить \x0D для CR"

кроме того, добавление -c (показать количество шаблонов сопоставлено) для grep полезно при поиске непечатаемых символов, поскольку соответствующие строки могут испортить терминал.

я обнаружил, что добавление диапазона 0-8 и 0x0e-0x1f (в диапазон 0x80-0xff) является полезным шаблоном. Это исключает вкладку, CR и LF и один или два более необычных печатаемых символа. Так ИМХО а довольно полезный (хотя и грубый) шаблон grep:

grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" *

поломки:

\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

например, практический пример использования find to grep все файлы в разделе текущий каталог:

find . -type f -exec grep -c -P -n "[\x00-\x08\x0E-\x1F\x80-\xFF]" {} + 

вы можете настроить grep время от времени. например, BS(0x08 - backspace) char используется в некоторых файлах для печати или для исключения VT (0x0b - vertical tab). Символы BEL(0x07) и ESC(0x1B) также могут считаться печатаемыми в некоторых случаях.

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

было бы интересно узнать, как искать один символ Юникода. Эта команда может помочь. Вам нужно только знать код в UTF8

grep -v $'\u200d'

Comments

    Ничего не найдено.