Существует хороший инструмент для установки Ваших цветов для команды ls - http://geoff.greer.fm/lscolors/
Если существует a NUL
изобразите где угодно в файле, grep рассмотрит это как двоичный файл.
Там мог бы обходное решение как это cat file | tr -d '\000' | yourgrep
устранить весь пустой указатель сначала и затем перерыть файл.
Файл /etc/magic
или /usr/share/misc/magic
имеет список последовательностей что команда file
использование для определения типа файла.
Обратите внимание, что двоичный файл может просто быть решением для нейтрализации. Иногда файлы со странным кодированием считают двоичными также.
grep
на Linux имеет некоторые опции обработать двоичные файлы как --binary-files
или -U / --binary
mbrlen()
. Пример и исходная интерпретация в: unix.stackexchange.com/a/276028/32558
– Ciro Santilli 新疆改造中心法轮功六四事件
12.04.2016, 23:51
Можно использовать strings
утилита, чтобы извлечь текстовое содержание из любого файла и затем передать его по каналу через grep
, как это: strings file | grep pattern
.
Один из моих текстовых файлов был внезапно рассматривается как двоичный GREP:
$ file foo.txt
foo.txt: ISO-8859 text
решение было Чтобы преобразовать его с помощью ICONV
:
iconv -t UTF-8 -f ISO-8859-1 foo.txt > foo_new.txt
У меня была такая же проблема. Я использовал VI -B [Имя файла]
, чтобы увидеть добавленные символы. Я нашел контрольные символы ^ @
и ^ м
. Тогда в VI тип : 1, $ S / ^ @ // G
для удаления символов ^ @
. Повторите эту команду для ^ м
.
ПРЕДУПРЕЖДЕНИЕ. Чтобы получить «синие» управляющие символы, нажмите CTRL + V затем Ctrl + M или Ctrl + @ . Тогда сохраните и выйдите из VI.
На вопрос "Что заставляет grep считать файл двоичным? ", вы можете использовать iconv
:
$ iconv < myfile.java
iconv: (stdin):267:70: cannot convert
В моем случае были испанские символы, которые правильно отображались в текстовых редакторах, но grep считал их двоичными; iconv
вывод указывал мне на номера строк и столбцов этих символов
В случае NUL
символов, iconv
будет считать их нормальными и не будет печатать такой вывод, поэтому данный метод не подходит
Один из моих учеников была эта проблема. Ошибка в grep
в Cygwin
. Если файл содержит символы, отличные от Ascii, grep
и egrep
воспринимают его как двоичный.
grep -a
работал у меня:
$ grep --help
[...]
-a, --text equivalent to --binary-files=text
GNU grep 2.24 RTFS
Вывод: только 2 и 2 случая:
NUL
, например printf 'a\0' | grep 'a'
ошибка кодировки согласно C99 mbrlen()
, например:
export LC_CTYPE='en_US.UTF-8'
printf 'a\x80' | grep 'a'
потому что \x80
не может быть первым байтом точки Юникода UTF-8: UTF-8 - Описание | en.wikipedia.org
Кроме того, как упоминал Стефан Шазелас Что заставляет grep считать файл бинарным? | Unix & Linux Stack Exchange, эти проверки выполняются только до первого чтения буфера длиной TODO.
Только до первого чтения буфера
Так что если в середине очень большого файла произойдет NUL или ошибка кодировки, он все равно может быть записан.
Я полагаю, что это сделано из соображений производительности.
Например: это печатает строку:
printf '%10000000s\n\x80a' | grep 'a'
а это нет:
printf '%10s\n\x80a' | grep 'a'
Фактический размер буфера зависит от того, как читается файл. Например, сравните:
export LC_CTYPE='en_US.UTF-8'
(printf '\n\x80a') | grep 'a'
(printf '\n'; sleep 1; printf '\x80a') | grep 'a'
При sleep
первая строка передается в grep, даже если ее длина всего 1 байт, потому что процесс уходит в сон, а при втором чтении не проверяется, является ли файл бинарным.
RTFS
git clone git://git.savannah.gnu.org/grep.git
cd grep
git checkout v2.24
Найдите, где кодируется сообщение об ошибке stderr:
git grep 'Binary file'
Привело нас к /src/grep.c
:
if (!out_quiet && (encoding_error_output
|| (0 <= nlines_first_null && nlines_first_null < nlines)))
{
printf (_("Binary file %s matches\n"), filename);
Если эти переменные были хорошо названы, мы в основном пришли к выводу.
encoding_error_output
Быстрый поиск по encoding_error_output
показывает, что единственный путь кода, который может его изменить, проходит через buf_has_encoding_errors
:
clen = mbrlen (p, buf + size - p, &mbs);
if ((size_t) -2 <= clen)
return true;
затем просто man mbrlen
.
nlines_first_null и nlines
Инициализированы как:
intmax_t nlines_first_null = -1;
nlines = 0;
поэтому когда найден null 0 <= nlines_first_null
становится true.
TODO когда nlines_first_null < nlines
может быть false? Мне стало лень.
POSIX
Не определяет бинарные опции grep - поиск в файле по шаблону | pubs.opengroup.org , а GNU grep не документирует это, так что RTFS - единственный способ.
У меня тоже была эта проблема, но в моем случае она была вызвана слишком длинной совпадающей строкой.
file myfile.txt
myfile.txt: UTF-8 Unicode text, with very long lines
grep
будет проходить через весь файл со многими шаблонами, но когда шаблон соответствует «очень длинной строке», он останавливается на Binary file myfile.txt matches
.
Добавление -a
также решает эту проблему, но предварительный -синтаксический анализ файла на наличие NULL или других недопустимых символов не будет иметь никакого эффекта (их нет, иначе grep не завершится для других шаблонов ). В этом случае оскорбительная строка содержала более 25 тысяч символов!
Чего я не понимаю, так это почему это происходит только тогда, когда grep
пытается вернуть строку, а не когда она обрабатывает ее в поисках других шаблонов.
-a
/--text
, по крайней мере, с GNU grep. – derobert 26.11.2012, 22:44NUL
(вероятно, becauses это называет C printf и дает ему подобранную строку?). В такой системе agrep cmd .sh_history
возвратит столько же пустых строк, сколько существуют строки, соответствующие 'cmd', поскольку каждая строка sh_history имеет определенный формат с aNUL
в начале каждой строки. (но Ваш комментарий, "по крайней мере, о GNU grep", вероятно, осуществляется. У меня нет того под рукой прямо сейчас для тестирования, но я ожидаю, что они обрабатывают это приятно), – Olivier Dulac 25.11.2013, 13:46grep
на рассмотренном двоичном файле cygwin, потому что это имело длинного тире (0x96) вместо регулярного дефиса/минус ASCII (0x2d). Я предполагаю, что этот ответ решил вопрос OP, но кажется, что это неполно. – cp.engr 15.02.2016, 18:15