我想列出以某个字节序列开头的文件。我的想法因相同的行为而失败:
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,但是更喜欢直接grepping的速度,而不是大量的管道处理和循环遍历递归文件名以及环绕文本异常。 2-1 / 2年前的一个先前的问题“用Bash雕刻文件无法用grep找到十六进制值FFD8或FFD9”非常接近,但是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应该只使用\ A选项查看文件的前2个字节。
响应破折号的答案...
我考虑了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想法按可打印字节序列的预期工作,并且没有文档对某些字节值进行例外处理,或建议“面向行”的想法无效。看一下文件实用程序,它对于ID文件类型来说非常酷,但是我发现没有简单的方法可以递归目录并打印出路径/文件名,并且仅当它具有任意的前导字节序列时才每行一个。最后,我有点像bash家伙..是的。我需要学习更多perl和python ..但我确定通用bash / grep组合可以按文档所述工作。
根据grep
手册,不支持'\ A`锚定,仅支持'^'和'$'
3.4 Anchoring
=============
The caret ‘^’ and the dollar sign ‘$’ are meta-characters that
respectively match the empty string at the beginning and end of a line.
They are termed “anchors”, since they force the match to be “anchored”
to beginning or end of a line, respectively.
另外,请记住grep是面向行的搜索实用程序。它几乎没有处理二进制文件的选项(--binary-files = binary,文本,不匹配)。它们都没有改变搜索的“性质”-它仍然会在lines
要考虑的两个选项
file
实用程序。它使用“魔术”数据库检查文件内容,并确定“文件类型”。它包括JPEG,PDF和更多类型。