NUL 分隔变量

NUL 分隔变量

GNU bash,版本 4.4.19(1)-release (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 字符串上下文中存储空字节。看为什么 $'\0' 或 $'\x0' 是空字符串?应该是空字符,不是吗?

一种选择是在排序命令之后去除空字节,在管道末尾使用tr并存储结果来解决抛出警告消息的直接问题。但这仍然会让你的逻辑有缺陷,因为带有换行符的文件名仍然会被破坏。

使用数组,使用mapfileor命令(在 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

shellbash不支持你想做的事情。外壳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
%

相关内容