【问题标题】:Parsing and storing the values of a csv file using shell script outputs :::: instead of actual characters使用 shell 脚本输出 :::: 而不是实际字符来解析和存储 csv 文件的值
【发布时间】:2016-11-03 06:01:12
【问题描述】:

我正在尝试使用 shell 脚本读取 csv 文件,使用以下命令。

cat file.csv | while read -r a b c d e f; do echo "$a:$b:$c:$d:$e:$f"; done

当我运行这个命令时,文件中的第一列没有被正确读取。

例如:如果第一列的内容是

number1,
number2,
number3,
number4,
(so on)

它输出:

::::er1,
::::er2,
::::er3,
::::er4,

一些字符被替换为':' 这只发生在第一列的内容上。我哪里错了?

【问题讨论】:

  • 在我看来,您在 Unix 机器上具有 DOS 样式的 CRLF 行尾。
  • @JonathanLeffler:IFS 的 not 设置不是造成了这里的问题吗?
  • 也是这样,但是行首的冒号向我表明,有一个 CR 作为数据的一部分保存(因为 Unix 行以 LF 结尾;CR 只是一个行字符)。所以,是的 - IFS 可能是问题的一部分,但数据可能来自 Windows,或者在某个时候通过 Windows 机器传输。

标签: bash shell csv scripting


【解决方案1】:

这个问题很可能是由于几个问题:-

  • 您正在阅读没有IFS=, 的文件
  • 您的csv 文件可能包含回车符(\r),这可能会破坏read 命令处理输入流的方式。

要删除回车符(\r),请使用tr -d '\r' < oldFile.csv > newFile.csv,并在新文件中进行如下所述的解析。

没有设置内部字段分隔符 (IFS=","),而从输入流中读取 read 不知道在哪里分隔你的单词。在下面的命令中添加相同的内容。

cat file.csv | while IFS="," read -r a b c d e f; do echo "$a:$b:$c:$d:$e:$f"; done

您可以看到它的工作方式如下。我有file.csv的内容如下。

$ cat file.csv
abc,def,ghi,ijk,lmn,opz
1,2,3,4,5,6

$ cat file.csv | while IFS="," read -r a b c d e f; do echo "$a:$b:$c:$d:$e:$f"; done
abc:def:ghi:ijk:lmn:opz
1:2:3:4:5:6

不推荐使用 cat 并循环它,bash 爱好者通常将其称为 UUOC - Useless Use Of Cat

你可以通过这样做来避免这种情况

#!/bin/bash

while IFS="," read -r a b c d e f;
do
    echo "$a:$b:$c:$d:$e:$f"
done < file.csv

【讨论】:

  • 非常感谢@inian 的详细解释,包括 IFS=','解决了我的问题。
  • 我投了赞成票,但它不是公开可见的,因为我仍然没有最低声誉。
猜你喜欢
  • 1970-01-01
  • 2021-08-12
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多