读取 nul 分隔字段

read nul delimited fields

鉴于此文件

printf 'alpha[=10=]bravo[=10=]charlie' > delta.txt

我想将字段读取到单独的变量中。我使用的原因 空分隔符是因为字段将包含文件路径,其中可以包含 除 null 之外的任何字符。我尝试了这些命令:

IFS= read mike november oscar < delta.txt
IFS=$'[=11=]' read mike november oscar < delta.txt

但是字段未正确拆分

$ echo $mike
alphabravocharlie

分配 IFS=$'[=12=]' 不会使空字符成为分隔符,因为 Bash variables cannot hold null charactersIFS=$'[=12=]' 等同于 IFS=,您可以通过以下方式验证:

bash-4.3$ IFS=$'[=10=]'
bash-4.3$ echo ${#IFS}
0

IFS= 根据定义意味着完全没有分词(参见 Bash Reference Manual)。

你可以做的是使用 read builtin-d 选项一个一个地读取空分隔的项目。根据链接文档,

-d delim

The first character of delim is used to terminate the input line, rather than newline.

我们可以为 delim 使用空字符串来获得所需的行为。

示例(我冒昧地在您的示例中添加了空格,以演示它如何实现所需的 — 不对空格进行拆分):

bash-4.3$ printf 'alpha with whitespace[=11=]bravo with whitespace[=11=]charlie with whitespace' > delta.txt
bash-4.3$ { read -r -d '' mike; IFS= read -r -d '' november; IFS= read -r -d '' oscar; echo $mike; echo $november; echo $oscar; } < delta.txt
alpha with whitespace
bravo with whitespace
charlie with whitespace

我还使用 -r 选项在输入文件中保留反斜杠。当然你可以在开头用一个cat delta.txt |代替< delta.txt

我知道逐一阅读很烦人,但我想不出更好的方法。

作为解决方法,我创建了这个函数

function read_loop {
  while [ "$#" -gt 0 ]
  do
    read -d '' ""
    shift
  done
}

使用示例

read-nul mike november oscar < delta.txt