Я хочу перечислить файлы, которые начинаются с определенной последовательности байтов. Мои идеи терпят неудачу с идентичным поведением:
grep -Rl $'\A\xff\xd8' .
grep -Rl \A$'\xff\xd8' .
grep -RlP "\A\xff\xd8" .
Тестовый файл, начинающийся с ff d8, не найден, в то время как найдено 3 других файла, которые имеют последовательность байтов в другом месте файла. Первые несколько байтов моего тестового файла подтверждаются с помощью hexdump -C.
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 |......JFIF......|
Я нашел несколько «почти» ответов. Я исследовал hexdump, но предпочитаю скорость прямого поиска, а не множество операций с рекурсивными именами файлов и обходом текстовых исключений. Предыдущий вопрос 2-1 / 2 года назад "При вырезании файлов с помощью Bash не удается найти шестнадцатеричные значения FFD8 или FFD9 с помощью grep", но он очень близок, но LC_ALL = C не меняет поведения. Игра с -a и -b не меняет поведение.
Как правильно это сделать? Я использую GNU grep 3.1.
/// Дальнейшее изучение заставляет меня думать, что у grep может быть такая же проблема. Код ниже показывает, что 2-байтовая последовательность не найдена, когда она не в начале. Затем найдена 2-байтовая последовательность, когда она есть в начале. Также в реальном jpg-файле совпадение найдено, когда оно в начале. Пока все хорошо.
dell@DELL-E6440:~$ echo $'\xffThis is a short test file I\xff\xd8 made' > junk.txt
dell@DELL-E6440:~$ hexdump -C junk.txt | head -n1
00000000 ff 54 68 69 73 20 69 73 20 61 20 73 68 6f 72 74 |.This is a short|
dell@DELL-E6440:~$ LC_ALL=C grep -lP "\A\xff\xd8" junk.txt
dell@DELL-E6440:~$ echo $'\xff\xd8This is a short test file I\xff\xd8 made' > junk.txt
dell@DELL-E6440:~$ hexdump -C junk.txt | head -n1
00000000 ff d8 54 68 69 73 20 69 73 20 61 20 73 68 6f 72 |..This is a shor|
dell@DELL-E6440:~$ LC_ALL=C grep -lP "\A\xff\xd8" junk.txt
junk.txt
dell@DELL-E6440:~$ hexdump -C avoid-powered.jpg | head -n1
00000000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 |......JFIF......|
dell@DELL-E6440:~$ LC_ALL=C grep -lP "\A\xff\xd8" avoid-powered.jpg
avoid-powered.jpg
dell@DELL-E6440:~$
Итак, почему оно сопоставляется в файле большего размера, когда оно НЕ в начале? Сначала покажите, что файл без необходимой 2-байтовой последовательности сопоставляется. Затем сохраните только начало реального файла, и 2-байтовая последовательность должным образом не найдена.
dell@DELL-E6440:~$ cp 130913-SEMSA.pdf junk.txt
dell@DELL-E6440:~$ hexdump -C junk.txt | head -n1
00000000 25 50 44 46 2d 31 2e 34 0a 31 20 30 20 6f 62 6a |%PDF-1.4.1 0 obj|
dell@DELL-E6440:~$ LC_ALL=C grep -lP "\A\xff\xd8" junk.txt
junk.txt
dell@DELL-E6440:~$ dd if=130913-SEMSA.pdf bs=10 count=1 of=junk.txt
1+0 records in
1+0 records out
10 bytes copied, 0.0062894 s, 1.6 kB/s
dell@DELL-E6440:~$ hexdump -C junk.txt | head -n1
00000000 25 50 44 46 2d 31 2e 34 0a 31 |%PDF-1.4.1|
dell@DELL-E6440:~$ LC_ALL=C grep -lP "\A\xff\xd8" junk.txt
dell@DELL-E6440:~$
Что может быть в файле полного размера, который дает ложное совпадение? grep должен искать только первые 2 байта файла с параметром \ A.
Ответ на ответ dash-o ...
Я рассмотрел руководство grep v3.3 https://www.gnu.org/software/grep/manual/grep.html, который говорит,
-P Interpret patterns as Perl-compatible regular expressions (PCREs)
и руководство по регулярным выражениям Perl https://www.tutorialspoint.com/perl/perl_regular_expressions.htm говорит,
\A Matches beginning of string.
Кроме того, идея \ A работает так, как и должнопечатаемые последовательности байтов, и никакая документация не делает исключения для определенных значений байтов или предполагает, что «ориентированные на строки» должны отрицать эту идею. Глядя на файловую утилиту, довольно здорово идентифицировать типы файлов, но я не вижу простого способа рекурсировать каталоги и распечатывать путь / имя файла, по одному на строку, если и только если она имеет произвольную последовательность начальных байтов. Наконец, я вроде парня из bash ... да ... мне нужно больше изучать Perl и Python ... но я бы хотел, чтобы универсальная комбинация bash / grep работала, как описано в документации.