ブロックデバイスで正規表現発生を検索する(ライン長バッファの問題)

ブロックデバイスで正規表現発生を検索する(ライン長バッファの問題)

#文字で始まり、1635700000から1653699999の間にあり、NULL文字(\0)またはLinux改行文字()で\0xA終わる2つのブロックデバイスのすべての数字を見つけようとします。

私が思いついたのは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

これはブロックデバイスの1つで動作しますが、他のデバイスでは一部の出力ではなく、一部の出力の後にエラーで停止します。

grep: exceeded PCRE's line length limit

\0故障したブロックデバイスに長いバイトがあり、文字がないか、行長制限\0xAしきい値を超えたようです。

だからNULL文字を改行文字に変更してみました。

sed 's/\x0/\n/g' /dev/device | grep ...

しかし、ほぼ同じ理由で停止します。

sed: regex input buffer length larger than INT_MAX

2番目のブロックデバイスで探しているものをどのように見つけますか?より大きな入力バッファを使用したり、行全体を読み取ったりしない他のユーティリティ、またはカスタムperl / python / C / C ++プログラムです。

見つかったバイトオフセットと数字を含む、見つかった一致ごとに1行を出力する必要があります。

ブロックデバイスの変更はオプションではありません。数万の結果があるため、16進エディタなどのツールで手動で検索することもオプションではありません。

ベストアンサー1

上記のコメントでは、@terdonは最初に検索スペースを減らすための重要な洞察を提供しました。 Perl(PCRE)grepパターン構文の最大行長を減らすために、拡張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)パターン構文エンジンに提供される最大行長が短くなります。

おすすめ記事