#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
реализаций. Если у вас есть GNUgrep
, попробуйте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
Проверка состоит в том, чтобы освободить пустые файлы, которые, конечно, вообще не содержат байтов (основная логика считывает нулевые байты и сдается, когда находит байт, который не является нулевым).