【问题标题】:Parsing a comma separated file in a bash script with a while loop使用while循环在bash脚本中解析逗号分隔的文件
【发布时间】:2016-06-26 16:59:42
【问题描述】:

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

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)时,脚本会立即终止而没有任何输出。

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

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

touch commafile.txt

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

cat commafile.txt

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

【问题讨论】:

  • 我还想知道是否有 IFS 不能使用的字符?像冒号、分号、克拉、星号、哈希符号等?还要提到的一件事是我在终端中创建了带有触摸的文件解析逗号。
  • 不,没有任何角色对 IFS 免疫。
  • 比你如何创建文件更重要的是你如何填充文件。例如,如果它缺少尾随换行符,那将导致您的错误(至少对于文件中的最后一行不可读)。
  • 我建议在您的问题中包含bash -x parsecommascat -v commafile.txt 的输出。
  • Word 不是 ASCII 编辑器。如果你从 Word 中得到一个看起来像逗号的字符,你不能假设它是一个逗号。

标签: bash shell parsing scripting command


【解决方案1】:

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

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

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

# 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

【讨论】:

  • 感谢您的回答!我想我会回去尝试重新创建问题并修复它。
猜你喜欢
  • 1970-01-01
  • 2013-04-19
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多