У меня есть несколько дампов базы данных из системы Windows на моем компьютере. Это текстовые файлы. Я использую Cygwin, чтобы просмотреть их. Они выглядят как простые текстовые файлы; Я открываю их с помощью текстовых редакторов, таких как блокнот и WordPad, и они выглядят разборчиво. Тем не менее, когда я запускаю grep на них, он скажет binary file foo.txt matches
.
Я заметил, что файлы содержат некоторые NUL
символы ascii , которые, как я считаю, являются артефактами из дампа базы данных.
Так что же заставляет grep считать эти файлы двоичными? NUL
Характер? Есть ли флаг в файловой системе? Что мне нужно изменить, чтобы программа grep показала мне совпадения строк?
--null-data
может быть полезно, еслиNUL
это разделитель.Ответы:
Если
NUL
в файле есть символ, grep будет рассматривать его как двоичный файл.Подобный обходной путь может сначала
cat file | tr -d '\000' | yourgrep
устранить все нули, а затем выполнить поиск по файлу.источник
-a
/--text
, по крайней мере, с GNU grep.NUL
(вероятно, потому, что он вызывает printf C и дает ей совпадающую строку?). В такой системе agrep cmd .sh_history
вернет столько пустых строк, сколько строк соответствует 'cmd', поскольку каждая строка sh_history имеет определенный формат сNUL
началом в начале каждой строки. (но ваш комментарий "по крайней мере, по GNU grep", вероятно, сбывается. У меня сейчас нет ни одного под рукой для тестирования, но я ожидаю, что они справятся с этим красиво)grep
на cygwin рассматривал двоичный файл, потому что он имел длинную черту (0x96) вместо обычного дефиса / минус ASCII (0x2d). Полагаю, этот ответ решил проблему ОП, но, похоже, он неполон.grep -a
работал на меня:источник
Вы можете использовать
strings
утилиту для извлечения текстового содержимого из любого файла , а затем по конвейеру черезgrep
, например:strings file | grep pattern
.источник
GNU grep 2.24 RTFS
Вывод: только в 2 и 2 случаях:
NUL
например,printf 'a\0' | grep 'a'
ошибка кодирования в соответствии с C99
mbrlen()
, например:потому что
\x80
не может быть первым байтом точки Unicode UTF-8 : UTF-8 - Описание | en.wikipedia.orgКроме того, как уже упоминал Стефан Шазелас, что заставляет grep считать файл двоичным? | Unix и Linux Stack Exchange , эти проверки выполняются только до первого чтения буфера длины TODO.
Только до первого чтения буфера
Таким образом, если в середине очень большого файла возникает ошибка NUL или кодировки, она может быть в любом случае обработана.
Я полагаю, это из соображений производительности.
Например: это печатает строку:
но это не
Фактический размер буфера зависит от того, как файл читается. Например, сравнить:
С помощью
sleep
первой строки передается grep, даже если длина ее составляет всего 1 байт, потому что процесс переходит в спящий режим, а второе чтение не проверяет, является ли файл двоичным.RTFS
Найдите, где закодировано сообщение об ошибке stderr:
Приводит нас к
/src/grep.c
:Если эти переменные были хорошо названы, мы в основном пришли к выводу.
encoding_error_output
Быстрый поиск
encoding_error_output
показывает, что единственный путь кода, который может изменить его, проходитbuf_has_encoding_errors
:тогда просто
man mbrlen
.nlines_first_null и nlines
Инициализировано как:
поэтому, когда ноль найден,
0 <= nlines_first_null
становится истиной.TODO когда может
nlines_first_null < nlines
быть ложным? Мне стало лень.POSIX
Не определяет бинарные параметры grep - поиск файла для шаблона | pubs.opengroup.org , а GNU grep не документирует это, поэтому RTFS - единственный путь.
источник
(printf '\n\0y') | grep y
с,(printf '\n'; sleep 1; printf '\0y') | grep y
например.export LC_CTYPE='en_US.UTF-8'
как в моем примере, или что-то еще? Buf read: удивительный пример, добавлен в ответ. Вы, очевидно, читали источник больше, чем я, напоминает мне о тех хакерских коанах "Ученик был просветленным" :-)Grep: один из моих текстовых файлов внезапно стал двоичным
Решением было преобразовать его, используя
iconv
:источник
0xFC
шестнадцатеричное, поэтому за пределами диапазона grep будет ожидать utf8 (до0x7F
). Проверьте с помощью printf 'a \ x7F' | grep 'a', как Сиро описал выше.Файл
/etc/magic
или/usr/share/misc/magic
содержит список последовательностей, которые командаfile
использует для определения типа файла.Обратите внимание, что двоичный файл может быть просто запасным решением. Иногда файлы со странной кодировкой также считаются двоичными.
grep
в Linux есть несколько опций для обработки двоичных файлов, таких как--binary-files
или-U / --binary
источник
mbrlen()
. Пример и исходная интерпретация по адресу: unix.stackexchange.com/a/276028/32558У одного из моих учеников была эта проблема. Есть ошибка
grep
вCygwin
. Если файл содержит символы, отличные от символов Ascii,grep
иegrep
считайте его двоичным.источник
На самом деле, отвечая на вопрос «Что заставляет grep считать файл двоичным?», Вы можете использовать
iconv
:В моем случае были испанские символы, которые правильно отображались в текстовых редакторах, но grep считал их двоичными;
iconv
вывод указал мне на номера строк и столбцов этих символовВ случае
NUL
символовiconv
будет считать их нормальными и не будет выводить такой вывод, поэтому этот метод не подходитисточник
У меня такая же проблема. Я привык
vi -b [filename]
видеть добавленных персонажей. Я нашел контрольные символы^@
и^M
. Затем в vi введите:1,$s/^@//g
для удаления^@
символов. Повторите эту команду для^M
.Предупреждение: чтобы получить «синие» управляющие символы, нажмите Ctrl+, vзатем Ctrl+ Mили Ctrl+ @. Затем сохраните и выйдите из vi.
источник