`grep -z -a -b -P --only-matching 'LUKS\xba\xbe'` は `LUKS\xba\xbe...` と一致しません

`grep -z -a -b -P --only-matching 'LUKS\xba\xbe'` は `LUKS\xba\xbe...` と一致しません

理解できません(https://ubuntuforums.org/showthread.php?t=1643334):

% grep -a -b -P --only-matching 'LUKS\xba\xbe' /dev/sde  ### does not match
% echo -e 'LUKS\xba\xbe...' | grep -a -b -P --only-matching 'LUKS' ### matches
0:LUKS
% echo -e 'LUKS\xba\xbe...' | grep -z -a -b -P --only-matching 'LUKS' ### matches
0:LUKS
% echo -e 'LUKS\xba\xbe...' | grep -z -a -b -P --only-matching 'LUKS\xba' ### does not match
% echo -e 'LUKS\xba\xbe...' | grep -z -a -b -P --only-matching 'LUKS\xba\xbe' ### does not match

grep が一致しないのはなぜですか (明らかに一致するはずです)。一致させるには何をする必要がありますか?

私はこれらのコマンドを Tails 4.18 と openSUSE Leap 15.2 で試しました。

答え1

TL;DR:grepコマンドは現在のロケールを使用して入力を解釈します。

あなたが示したように、これは一致しません:

echo -e 'LUKS\xba\xbe...' | grep -z -a -b -P --only-match 'LUKS\xba'

さらに、.すべてに一致するはずの も一致しません。

echo -e 'LUKS\xba\xbe...' | grep -z -a -b -P --only-match 'LUKS.'

ただし、このセッションのロケールを設定すると...

export LC_ALL=C

そしてもう一度試してみると、うまくいきます:

echo -e 'LUKS\xba\xbe...' | grep -z -a -b -P --only-match 'LUKS\xba'

ロケールはシ​​ステムの設定によって異なります。 と入力localeすると、すべてのロケール情報が表示されます。私のシステムでは、デフォルトのロケールは です。これは、が入力が UTF8 であると想定しており、入力(16 進数) が有効な UTF8 シーケンスではないLC_CTYPE="en_US.UTF-8"ことを意味していると思います。Grepのマニュアル ページを参照してください。また、「ピリオド . は任意の 1 文字と一致します」と記載されていることにも注意してください。 grepLUKS\xba\xbe...4c 55 4b 53 ba be 2e 2e 2eLC_ALL, LC_CTYPE, LANGエンコードエラーに一致するかどうかは未指定です。「(強調は筆者による)」

関連情報