NUL で区切られた変数

NUL で区切られた変数

GNU bash、バージョン 4.4.19(1) リリース (x86_64-pc-linux-gnu)

アイデアは、変数をNULで区切られたデータセットに設定することです。ここで$samples

しかし、その結果は次のようになります。

警告: コマンド置換: 入力内のヌルバイトは無視されました

行う場合:

samples="$(find . -type d -iregex './sample[0-9][0-9]' -printf "%f\0" | sort -z)"

同じ値を複数回繰り返す必要があるため、この変数を再利用できると考えました。

while IFS= read -rd '' sample; do
    echo $sample
done<<< "$samples"

私は\n\0探すまさにこのケースではコマンドを実行できませんが、可能であれば、一般的に NUL 区切り文字を使用してそれを実行する方法を知りたいです。

オプションで以下も実行できます:

while IFS= read -rd '' sample; do
    echo $sample
done< <(find . -type d -iregex './E[0-9][0-9]' -printf "%f\0" | sort -z)

しかし、これを何度もループする必要があるため、非常に冗長なコードになり、探すそして選別毎回コマンドを実行します。

結果を配列に変換するのでしょうか?


  • これは可能ですか?
  • NUL で区切られたデータをそのまま使用できないのはなぜですか?

答え1

\0基礎となるCの実装のため、bashの文字列コンテキストにnullバイトを格納することはできないのは事実です。なぜ $'\0' または $'\x0' は空の文字列なのでしょうか? ヌル文字であるべきではないでしょうか?

1 つのオプションは、ソート コマンドの後の null バイトを削除し、パイプラインの最後でtr結果を保存して、警告メッセージがスローされるという当面の問題を解決することです。ただし、改行を含むファイル名は依然として壊れているため、ロジックに欠陥が残ります。

配列を使用し、mapfileまたはコマンド(bash 4.4以降)を使用して、コマンドreadarrayの結果を直接取得します。find

IFS= readarray -t -d '' samples < <(find . -type d -iregex './sample[0-9][0-9]' -printf "%f\0" | sort -z)

答え2

シェルbashは、あなたがやりたいことをサポートしていません。zshシェルはすぐに使えます。

% mkdir sample11 SAMple12 sample21 sample22 dir1
% ll
total 20
drwxrwxr-x 2 fpm fpm 4096 Jun  9 13:46 dir1
drwxrwxr-x 2 fpm fpm 4096 Jun  9 13:46 sample11
drwxrwxr-x 2 fpm fpm 4096 Jun  9 13:46 SAMple12
drwxrwxr-x 2 fpm fpm 4096 Jun  9 13:46 sample21
drwxrwxr-x 2 fpm fpm 4096 Jun  9 13:46 sample22
% samples=$(find . -type d -iregex './sample[0-9][0-9]' -print0 | sort -z)
% echo $samples
./sample11./SAMple12./sample21./sample22
% echo $samples | od -a
0000000   .   /   s   a   m   p   l   e   1   1 nul   .   /   S   A   M
0000020   p   l   e   1   2 nul   .   /   s   a   m   p   l   e   2   1
0000040 nul   .   /   s   a   m   p   l   e   2   2 nul  nl
0000055
%

関連情報