Поиск файлов с содержимым 0x00

#regex #windows #grep

Вопрос:

Я ищу простой и быстрый способ поиска файлов, которые содержат только 0x00. Это жесткий диск объемом 8 ТБ, и какое-то копирование пошло не так. Имена и размеры файлов в порядке, но они содержат только 0x00. Я пробовал wingrep с x00{100} этим работает, но ищет весь файл и подсчитывает, как часто шаблон будет совпадать, и это займет слишком много времени. Итак, я написал короткую программу на C , которая выполнит эту работу, прочитав только первые 100 байт, но мне интересно, как я могу использовать регулярное выражение, чтобы сказать, что оно должно проверять только первое совпадение, а затем переходить к следующему файлу?

Спасибо — это работает с `A.*?x00{100}. Но это позволит найти все совпадения в файле — даже в конце. Я посмотрел, но не нашел флага a, который ограничит область поиска (например, от индекса 0 до индекса 101). Хорошо — я сделал это в своей программе, но возможно ли просто использовать для этого регулярное выражение?

Комментарии:

1. Попробуй A.*?x00{100}

2. Возможно, обратите внимание, что A и *? являются расширениями Perl, которые не поддерживаются большинством grep реализаций. Если у вас есть GNU grep , попробуйте grep -P включить эти функции.

3. @tripleee OP упоминает wingrep (на самом деле, так оно и есть grepWin ), что он основан на библиотеке регулярных выражений .NET.

4. Попробуйте включить флажок «Только один экземпляр».

Ответ №1:

Поскольку вы используете grep , я полагаю, что у вас есть подсистема Linux или Cygwin на вашем компьютере с Windows для имитации команд Linux.

Одна из таких команд head , которая позволяет видеть только первые n байты ( head -c ) или строки ( head -n ). Вы можете использовать это в качестве входных данных для вашего grep .

Комментарии:

1. Они говорят, что используют «wingrep», но я не могу узнать, каковы функции этого инструмента.

Ответ №2:

grep -m 1 находит первое совпадение и уходит. grep -l аналогично завершается после поиска совпадения и печати имени файла. Но если ваша задача действительно состоит в том, чтобы найти файлы, которые больше ничего не содержат, я думаю, вы хотите grep -L '[^x00]' (предполагая, что у вас есть GNU-подобный grep , который поддерживает -L опцию и x00 шестнадцатеричный побег).

Если у вас есть Python, вот простая программа для проверки всех ваших файлов.

 from pathlib import Path

for file in Path('c:/').rglob('*'):
    if not file.is_file():
        continue
    try:
        with open(file, 'rb') as fh:
            found = False
            nonempty = False
            while not found:
                buf = fh.read(1024)
                for byte in buf:
                    nonempty = True
                    if byte != b'x00':
                        found = True
                if len(buf) < 1024:
                    if not found and not nonempty:
                        print(file)
                    break
    except PermissionError as err:
        print(file, err)
 

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