我试图在两个以#字符开头、介于1635700000到1653699999之间、以空字符(\0)或linux (\0xA)结尾的块设备上查找所有数字。
我想出了一个绝对不优雅的grep:
grep --only-matching --byte-offset --text -Pa '#1635[7-9][0-9]{5}(\x0|$)|#163[6-9][0-9]{6}(\x0|$)|#164[0-9]{7}(\x0|$)|#165[0-2][0-9]{6}(\x0|$)|#1653[0-6][0-9]{5}(\x0|$)' /dev/device即使不能像这样输入和执行它,这里还是有一些换行符的相同语句,以提高它的可读性。
grep --only-matching --byte-offset --text -Pa '
#1635[7-9][0-9]{5}(\x0|$)
|#163[6-9][0-9]{6}(\x0|$)
|#164[0-9]{7}(\x0|$)
|#165[0-2][0-9]{6}(\x0|$)
|#1653[0-6][0-9]{5}(\x0|$)
' /dev/device这在其中一个块设备上有效,但是在另一个块设备上,在一些但不是所有的输出之后,它停止了错误:
grep: exceeded PCRE's line length limit我猜失败的块设备有更长的字节段,没有\0或\0xA字符,超过了行长限制阈值。
因此,我尝试将空字符更改为换行符:
sed 's/\x0/\n/g' /dev/device | grep ...但是,它停止的原因大致相同:
sed: regex input buffer length larger than INT_MAX我怎样才能在第二个街区设备上找到我想要找到的东西呢?非常肯定,它需要一个不同的实用程序,要么使用更大的输入缓冲区,要么不读取整行,甚至可能是定制的perl/python/C/C++程序。
我确实需要每个匹配的输出为一行,包括字节偏移量和找到的数字。
修改块设备不是一个选项。将会有成千上万的结果,所以手工搜索类似于十六进制编辑器也不是一种选择。
发布于 2022-06-20 20:55:44
在上面的评论中,@terdon首先给出了减少搜索空间的关键见解。通过使用扩展的grep模式语法来减少给perl (PCRE) grep模式语法的最大行长度,我能够让它工作起来。
grep --only-matching --byte-offset --text -E '#[0-9]{10}.' /dev/device | grep --only-matching --text -P '[0-9]*:#1635[7-9][0-9]{5}(\x0|$)|[0-9]*:#163[6-9][0-9]{6}(\x0|$)|[0-9]*:#164[0-9]{7}(\x0|$)|[0-9]*:#165[0-2][0-9]{6}(\x0|$)|[0-9]*:#1653[0-6][0-9]{5}(\x0|$)' /dev/device即使不能像这样输入和执行它,这里还是有一些换行符的相同语句,以提高它的可读性。
grep --only-matching --byte-offset --text -E
'#[0-9]{10}.'
/dev/device
| grep --only-matching --text -P '
[0-9]*:#1635[7-9][0-9]{5}(\x0|$)
|[0-9]*:#163[6-9][0-9]{6}(\x0|$)
|[0-9]*:#164[0-9]{7}(\x0|$)
|[0-9]*:#165[0-2][0-9]{6}(\x0|$)
|[0-9]*:#1653[0-6][0-9]{5}(\x0|$)
' /dev/device扩展的grep模式语法引擎没有我遇到的行长限制,并且减少了给perl (PCRE)模式语法引擎的最大行长。
发布于 2022-07-21 05:07:06
下面是一个使用bash(1)、grep(1)和perl(1)的解决方案:
1 #!/bin/bash
2 grep -P -a -b -o '#\d{10}(\000|$)' \
3 | perl -ne '/(\d{10})/; print if 1635700000 <= $1 && $1 <= 1653699999' \
4 | perl -pe 'chop; /\000/ ? do {chop; $_ .= "\\000\n"} : do {$_ .= "\\n\n"}'第1行告诉shell这是一个Bash脚本。
第2-4行形成一个命令管道.
第2行调用grep(1):
第3行是一个Perl单行过滤器,它只传递数值部分在所需范围内的行。
第4行是一个Perl一行程序,它使终止的换行符或NUL可见。
下面是一个示例运行:
52:#1647787407\n
70:#1644931194\n
84:#1651134631\000
154:#1646920743\nhttps://unix.stackexchange.com/questions/706741
复制相似问题