posix shell:读取带有从文本文件到变量的空格的条目

时间:2016-06-03 11:29:39

标签: sh

我想在脚本之间传递(大量)信息,理想情况下,脚本的输入/输出是持久的。 使用简单的文本文件似乎很合适,但只要条目有空格就会出现问题。

将变量存储在一个shell脚本中并在另一个shell脚本中读取它们的首选方法是什么?

在下面的示例中,我希望输出为

'publicname' 'x86' '"test directory"' '5' rem:'some other parameters in the future'

版本1: 这将是我首选的文本文件格式,无需转义,空格将在引号内输入。

echo 'publicname x86 "test directory" 5 some other parameters in the future
' >/tmp/input.txt
while read -r name archname vcdir rev rem; do
  set -e
  [ -n "$name" -a "$name" != "#" ] || continue
  echo "'$name' '$archname' '$vcdir' '$rev' rem:'$rem'"
done < /tmp/input.txt

输出

'publicname' 'x86' '"test' 'directory"' rem:'5 some other parameters in the future'

版本2: 产生正确的输出,输入需要为shell转义。这是有问题的,因为理想情况下输入将与其他语言一起使用,并且也由shell脚本生成(需要转义变量以便导出)

echo 'publicname x86 test\ directory 5 some other parameters in the future
' >/tmp/input.txt
while read name archname vcdir rev rem; do
  set -e
  [ -n "$name" -a "$name" != "#" ] || continue
  echo "'$name' '$archname' '$vcdir' '$rev' rem:'$rem'"
done < /tmp/input.txt

1 个答案:

答案 0 :(得分:0)

一般规则是:使用无法出现在字段中的分隔符。让我们说逗号是安全的:

echo 'publicname,x86,test directory,5,some other parameters in the future' > /tmp/input.txt
while IFS=, read -r name archname vcdir rev rem; do
  printf "'%s' '%s' '%s' '%s' rem:'%s'\n"  "$name" "$archname" "$vcdir" "$rev" "$rem"
done < /tmp/input.txt

如果逗号可能出现在某个字段中,您可能需要尝试一个不太常见的分隔符,例如ASCII控制字符。

printf 'publicname\037x86\037test directory\0375\037some other parameters in the future\n' > /tmp/input.txt
while IFS=$(printf '\037') read -r name archname vcdir rev rem; do
  printf "'%s' '%s' '%s' '%s' rem:'%s'\n"  "$name" "$archname" "$vcdir" "$rev" "$rem"
done < /tmp/input.txt

更简单的替代方法是使用换行符,然后多次调用read

printf 'publicname\nx86\ntest directory\n5\nsome other parameters in the future\n' > /tmp/input.txt
while read -r name; read -r archname; read -r vcdir; read -r rev; read -r rem; do
    printf "'%s' '%s' '%s' '%s' rem:'%s'\n"  "$name" "$archname" "$vcdir" "$rev" "$rem"
done < /tmp/input.txt

作为最后的手段,您可以尝试使用null字符作为分隔符。 [没有例子,因为我在如何处理Posix shell中的空分隔数据,但如果你没有一个可行的解决方案,那么shell可能不是正确使用的语言。]