在bash中解析.csv文件,而不是读取最后一行

时间:2012-08-06 02:49:26

标签: bash parsing shell unix csv

我正在尝试解析我使用Google Spreadsheet制作的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

关于我如何阅读最后一行并回应它的任何想法?

提前致谢。

3 个答案:

答案 0 :(得分:6)

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

#!/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

答案 1 :(得分:2)

cat file |sed -e '${/^$/!s/$/\n/;}'| while IFS=',' read -r last first; do echo "$last $first"; done

答案 2 :(得分:1)

如果最后一条(未终止的)行需要与其他行进行不同的处理,那么带有额外if语句的@ paxdiablo版本就可以了。但如果要像所有其他人一样处理它,那么在主循环中处理它会更清晰。

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

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