【问题标题】:Parsing .csv file in bash, not reading final line在 bash 中解析 .csv 文件,而不是读取最后一行
【发布时间】:2012-08-06 02:49:26
【问题描述】:

我正在尝试解析我使用 Google 电子表格制作的 csv 文件。用于测试目的非常简单,基本上是:

1,2
3,4
5,6

问题是 csv 没有以换行符结尾,所以当我 cat BASH 中的文件时,我得到了

MacBook-Pro:Desktop kkSlider$ cat test.csv 
1,2 
3,4 
5,6MacBook-Pro:Desktop kkSlider$ 

我只想使用每个指南建议的 while 循环在 BASH 脚本中逐行阅读,我的脚本如下所示:

while IFS=',' read -r last first
do
    echo "$last $first"
done < test.csv

输出是:

MacBook-Pro:Desktop kkSlider$ ./test.sh
1 2
3 4

关于如何让它读取最后一行并回显它的任何想法?

提前致谢。

【问题讨论】:

  • 我不确定你的最终目标是什么,尽管坚持使用传统的 Unix 命令可能更容易,例如 sedcut

标签: bash parsing shell unix csv


【解决方案1】:

您可以强制循环的输入以换行符结束:

#!/bin/bash
(cat test.csv ; echo) | while IFS=',' read -r last first
do
    echo "$last $first"
done

不幸的是,如果输入末尾已经有换行符,这可能会导致输出末尾出现空行。你可以通过一些补充来解决这个问题:

!/bin/bash
(cat test.csv ; echo) | while IFS=',' read -r last first
do
    if [[ $last != "" ]] ; then
        echo "$last $first"
    fi
done

另一种方法依赖于 read 将值放置到变量中,但由于 while 语句,它们没有被输出:

#!/bin/bash
while IFS=',' read -r last first
do
    echo "$last $first"
done <test.csv
if [[ $last != "" ]] ; then
    echo "$last $first"
fi

该方法无需创建另一个子shell 即可修改while 语句的输入。


当然,我在这里假设您希望在循环中做更多的事情,只输出带有空格而不是逗号的值。如果您只想这样做,还有其他工具比bash 读取循环更适合,例如:

tr "," " " <test.csv

【讨论】:

  • 非常感谢,这成功了!我仍然感到困惑的一件事是为什么 CSV 在最后一行的末尾没有换行符。
  • 这将是任何程序生成文件的责任。
【解决方案2】:
cat file |sed -e '${/^$/!s/$/\n/;}'| while IFS=',' read -r last first; do echo "$last $first"; done

【讨论】:

    【解决方案3】:

    如果最后(未终止的)行需要与其他行不同的处理,@paxdiablo 的版本带有额外的if 语句是可行的方法;但如果要像所有其他人一样处理它,在主循环中处理它会更干净。

    您可以将“如果最后一行未终止”滚动到主循环条件中,如下所示:

    while IFS=',' read -r last first || [ -n "$last" ]
    do
        echo "$last $first"
    done < test.csv
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2015-10-28
      • 2012-09-28
      • 2013-03-07
      • 1970-01-01
      相关资源
      最近更新 更多