выяснить все номера строк с двоичными нетекстовыми символами большого лог-файла

Preface: Хотя может быть очень приятно проголосовать за такой ответ и на этом закончить, пожалуйста, будьте уверены, что сопровождающие GNU coreutils не заботятся о голосах за ответ SO, и что если вы действительно хотите побудить их к изменениям, вам нужно написать им, как описано в этом ответе.


Обновление 2019 года:
В этом году мейнтейнеры удвоили свои усилия и теперь предлагают на все сообщения bug-coreutils@gnu.org об этой проблеме только шаблонный ответ, указывающий на невероятно длинную страницу на их сайте с перечнем проблем, которые люди имеют с этим изменением и которые они обязались игнорировать.
Непрекращающееся давление со стороны отчетов bug-coreutils@gnu.org явно возымело эффект, заставив создать эту огромную и абсурдную страницу, и потенциально сократив число сопровождающих, готовых заняться этой проблемой, до одного.
Когда столько людей считают какую-то вещь ошибкой, тогда это ошибка, независимо от того, согласны с этим мейнтейнеры или нет.
Продолжать писать им остается самым простым способом стимулировать изменения.


"Почему это происходит?"

Несколько сопровождающих coreutils решили, что они знают лучше, чем десятилетия стандартов де-факто.


"Как правильно это остановить?"

http://www.gnu.org/software/coreutils/coreutils.html:

Сообщения об ошибках

Если вы считаете, что нашли ошибку в Coreutils, то, пожалуйста, отправьте как можно более полное сообщение об ошибке по адресу

. полное сообщение об ошибке по адресу , и оно оно будет автоматически внесено в систему отслеживания ошибок Coreutils. Прежде чем прежде чем сообщать об ошибках, пожалуйста, прочитайте FAQ. Очень полезное и часто упоминаемое руководство о том, как писать сообщения об ошибках и задавать хорошие вопросы - это документ How To Ask Questions The Smart Way . Вы можете просмотреть предыдущие сообщения и поискать в архиве bug-coreutils.

Дистры, которые уже отменили это изменение:

  • Debian coreutils-8. 25-2
    • Включая, следовательно, предположительно, Ubuntu и все сотни Debian-based и Ubuntu-based производных

Дистрибутивы, не затронутые:

  • openSUSE (уже используется -N)

"Есть способ исправить это без перекомпиляции?"

Сторонники хотели бы, чтобы вы...

вернуться к старому формату, добавив -N к их псевдониму ls

... на всех ваших установках, везде, до конца вечности".

0
25.02.2019, 11:21
1 ответ

То, что GNU grepсчитает не -текстом, зависит от версии и локали.

В первом приближении можно попробовать:

grep -anPe '^((?!.*$)|.*\0)' < file.log

То есть ищите строки, содержащие символ NUL, 0 байт (, которые, вероятно, являются причиной этого сообщения Двоичный файл , если ваш файл журнала был усечен, когда он был открыт для записи каким-либо процессом без O _APPEND )или не -символы (возможны, если вы находитесь в локали с многобайтовой кодировкой, такой как UTF -8, и некоторые строки были выведены в другой кодировке ).

Это предполагает, что ваш GNU grepбыл собран с поддержкой PCRE (для-P).

Вы можете захотеть направить этот вывод на что-то вроде sed -n l, hexdump -Cилиod -vtc -tx1(и, возможно, опустить параметр -nдля grep), чтобы попытаться идентифицировать те последовательности байтов, которые вызывают двоичный код . сообщение.

Обратите внимание, что grep -aне пропускает эти строки, он просто указывает GNU grepне обрабатывать файлы, которые он рассматривает как двоичные . Строки с этими 0 байтами или символами, отличными от -, все равно будут сообщены, если они соответствуют шаблону.

По крайней мере, в Linux и большинстве собственных файловых систем вы можете определить, является ли файл разреженным, т. е. имеет ли он нераспределенные части (дыры ), которые кажутся заполненными нулевыми байтами с помощью:

perl -le '
  seek STDIN,0,4 or die; $hole = tell STDIN;
  seek STDIN, $hole, 3 and $data = tell STDIN;
  seek STDIN, 0, 2; $end = tell STDIN;
  if ($hole != $end) {
    print "at least one hole at offset $hole, length ".(($data||$end) - $hole)
  }' < file.log

Дыры будут создаваться всякий раз, когда пробел в противном случае будет включать по крайней мере один полный блок файловой системы (, обычно 4 КБ ). Вероятно, по обе стороны от этой дыры будет больше байтов NUL.

1
28.01.2020, 02:40

Теги

Похожие вопросы