【问题标题】:read nul delimited fields读取 nul 分隔字段
【发布时间】:2015-07-05 06:46:45
【问题描述】:

鉴于此文件

printf 'alpha\0bravo\0charlie' > delta.txt

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

IFS= read mike november oscar < delta.txt
IFS=$'\0' read mike november oscar < delta.txt

但是字段没有被正确分割

$ echo $mike
alphabravocharlie

【问题讨论】:

  • 我不相信文件路径包含除 null 之外的任何字符。

标签: bash nul


【解决方案1】:

赋值IFS=$'\0' 不会使空字符成为分隔符,因为Bash variables cannot hold null characters。 IFS=$'\0' 等价于IFS=,您可以通过以下方式进行验证:

bash-4.3$ IFS=$'\0'
bash-4.3$ echo ${#IFS}
0

而IFS= 的定义是完全没有分词(参见Bash Reference Manual)。

您可以使用read builtin 的-d 选项逐一读取以空分隔的项目。根据链接文档,

-d delim

delim 的第一个字符用于终止输入行,而不是换行。

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

示例(我冒昧地在您的示例中添加了空格,以演示它如何实现所需的功能 - 没有在空格上分割):

bash-4.3$ printf 'alpha with whitespace\0bravo with whitespace\0charlie 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 选项在输入文件中保留反斜杠。当然,您可以在开头将&lt; delta.txt 替换为cat delta.txt |。

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

【讨论】:

【解决方案2】:

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

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

示例使用

read-nul mike november oscar < delta.txt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2015-08-02
    • 2020-12-14
    • 2021-08-20
    相关资源
    最近更新 更多