使用 while 循环解析 bash 脚本中的逗号分隔文件

Parsing a comma separated file in a bash script with a while loop

我正在尝试解析类似于以下内容的逗号分隔文件,并将每个字段提取到一个变量中:

bob,mechanic,single,swimming,/bob/tmp,batman,
joe,architect,married,tennis,/joe/tmp,superman,34

使用此脚本:

#!/bin/bash

#|| [[ -n "$input" ]]

while IFS=, read -r a b c d e f g; do
    echo "$a"

done < "commafile.txt"

但是当我从命令行 运行 带有 ./parsecommas 的脚本(称为 parsecommas)时,脚本立即终止,没有任何输出。

我做错了什么?我正在 运行ning OSX Yosemite 并使用 xcode 编辑脚本,然后终端到 运行 它。我已经检查了有缺陷的隐身物,但发现了 none。 commafile.txt 与 bash 脚本 parsecommas 在同一目录中。

编辑:在 运行 运行一个 C++ 程序并且只能读取文件的最后一行之后,我意识到这个问题可能不是我的代码而是我使用的方法用于创建文本文件。我用了

touch commafile.txt

创建我的文件,在 C++ 程序中使用 getline(file, line) 时我只能读取文件的最后一行。以前有其他人 运行 遇到过这个问题吗?我的 Mac/Text 编辑器可能出了什么问题?

cat commafile.txt

仅打印文件中的最后一行,而当我在 XCode 或 TextEditor 中打开文件时,所有行都会显示。我将一个 word 文档的内容复制粘贴到一个框形字段中 commafile.txt.

如果 cat filename 只打印最后一行,这意味着您的文件几乎肯定使用 CR(回车 returns,\r)而不是 LF(\n)或 CRLF (\r\n) 换行符。您可以通过如下创建文件来重现此错误:printf '%s\r' "bob,mechanic,single,swimming,/bob/tmp,batman," "joe,architect,married,tennis,/joe/tmp,superman,34" >commafile.txt

这导致 cat 只显示文件的最后一行,因为 \r 字符导致光标返回到同一行的开头 在记录之间转换时。这解释了您的错误,因为 read shell 内置函数需要一个有效的 UNIX 行,该行由 \n 终止;如果您的代码不包含 \n,则 read 将 return 为假值并且循环不会 运行.

您可以按如下方式解决此问题:

# replace \r characters with \n
tr '\r' '\n' <commafile.txt >commafile.fixed && mv commafile{.fixed,.txt}

或者,您可以通过将 -d $'\r' 传递给 read:

来修改循环以期望使用此格式而不是标准的 UNIX 文本文件
while IFS=, read -r -d $'\r' a rest; do
  printf '%s\n' "$a" # less buggy than echo
done