Файлы, которые я пытаюсь найти/перечислить:
Команда, которую я имею теперь:
grep -RLP '[^\x00]' .
Который работает, но это также находит файл, который состоит только из двух байтов: 0xFF, 0xFE. Не знайте почему.
Там какая-либо лучшая команда должна найти такие файлы?
Короче говоря, что происходит, вот это grep
попытка состоит в том, чтобы интерпретировать Ваш файл как данные Unicode. Последовательность 0xFF, 0xFE является Маркером Порядка байтов для UTF-16.
(В моем тестировании даже другие последовательности, включающие два 0xFF или два 0xFE и т.д., все еще не соответствовали бы '[^\x00]'
regex, с тех пор пытаясь сделать UTF-8 их считали бы несимволами.)
Используя локаль, которая не использует Unicode для типов символов, должен зафиксировать это, которое можно выполнить путем установки переменной среды LC_CTYPE. Используйте C
локаль для принуждения кодирования ASCII (таким образом, никакой Unicode не включил):
LC_CTYPE=C grep -RLP '[^\x00]' .
ОБНОВЛЕНИЕ: Как указано @steeldriver, grep все еще действует на линию за линией основание, таким образом, файлы, содержащие байты NUL и новые строки, будут все еще соответствовать.
Решение @DavidFoerster с помощью grep's -z
делает хорошее задание решения этой проблемы, с помощью байтов NUL, поскольку разделители добиваются цели.
С другой стороны, я придумал короткий сценарий Python 3 (allzeroes.py
) чтобы проверить, является ли содержание файла, все обнуляет:
#!/usr/bin/python3
import sys
assert len(sys.argv) == 2
with open(sys.argv[1], 'rb') as f:
for block in iter(lambda: f.read(4096), b''):
if any(block):
sys.exit(1)
Который можно использовать в a find
определять местоположение всех соответствий рекурсивно:
$ find . -type f -exec allzeroes.py {} \; -print
Я надеюсь, что это помогает.
Я предоставлю другой ответ, который я использую. Запущенный из определенной папки вернется и выведет список всех файлов NUL:
shopt -s globstar
for file in ./**
do
[ -d "$file" ] || LC_CTYPE=C grep -qP '[^\x00]' "$file" || echo "$file"
done
Можно злоупотребить grep
альтернативный режим пустой нагруженной линии и таким образом ищет файлы, которые содержат только пустые строки:
grep -L -z -e . ...
Замена ...
с набором файла, который Вы хотите просканировать (здесь: -R .
).
Объяснение
-z
, --null-data
– Рассматривайте вход как ряд строк, каждый завершенный нулевым байтом (символ ASCII NUL) вместо новой строки 1-e .
– Использовать .
как шаблон поиска, т.е. соответствие любой символ.-L
, --files-without-match
– Подавите нормальный вывод; вместо этого распечатайте название каждого входного файла, из которого обычно не печатался бы никакой вывод. Сканирование остановится на первом соответствии 1Тест
Установка:
: > empty
truncate -s 100 zero
printf '%s\0' foo bar > foobar
Запущенный тест:
$ grep -L -z -e . empty zero foobar
empty
zero
Вы можете использовать этот код PHP для поиска всех файлов с содержимым NULL.
<?php
$pattern = '';
$directory = new RecursiveDirectoryIterator("./");
$iterator = new RecursiveIteratorIterator($directory);
if ($pattern) {
$regex = new RegexIterator($iterator, $pattern);
} else {
$regex = $iterator;
}
foreach($regex as $file) {
if (is_dir($file)) continue;
$contens = file_get_contents($file);
$contens = trim($contens);
if (strlen($contens) == 0) {
echo "$file\n";
}
}