【问题标题】:How to read in n columns of CSV fie to check they are null?如何读取 CSV 文件的 n 列以检查它们是否为空?
【发布时间】:2014-04-14 11:48:25
【问题描述】:

我正在尝试读取具有这种格式的电子表格

username,   lastname,   firstname,    x1,      x2,       x3,      x4
user1,       dudette,    mary,         7,       2,                 4
user2,       dude,       john,         6,       2,        4,
user3,       dudest,     rad,
user4,       dudaa,      pad,          3,       3,        5,       9

基本上,它有用户名、这些用户名对应的名称以及每个 x 的值。我想要做的是从一个 csv 文件中读取这个,然后找到所有的空格并用 5s 填充它们。我这样做的方法是读取整个数组,然后用 0 替换所有空空格。这是目前为止的代码...

感谢 stackoverflow 上的另一位受访者,我得到的解决方案是

n=5
while IFS=, read username lastname firstname x1 x2 x3 x4; do
    ! [[ $x1 ]] && x1=$n
    ! [[ $x2 ]] && x2=$n
    ! [[ $x3 ]] && x3=$n
    ! [[ $x4 ]] && x4=$n
    echo $username,$lastname,$firstname,$x1,$x2,$x3,$x4
done < something.csv > newfile.csv && mv newfile.csv something.csv

在过去的几个小时里,我一直在试图弄清楚如何将其扩展到 n 列的情况。所以在上面的例子中,我知道我有 7 列,所以我有 7 个变量读入。我现在要做的是弄清楚如何将它扩展到 n 列的情况。即使添加了另一列,我仍然需要代码才能工作。

【问题讨论】:

  • IFS=, read username lastname firstname x1 x2 x3 x4; :将其更改为 IFS=, read -a columns; 然后解析名为 columns 的数组

标签: arrays linux bash variables csv


【解决方案1】:

awk 更适合这种类型的 csv 解析和格式化。

awk -F '[, ]+' -v n=7 '{for (i=1; i<=n; i++) printf "%10s%s", $i, (i<n)?OFS:RS}' OFS=, x
  username,  lastname, firstname,        x1,        x2,        x3,        x4
     user1,   dudette,      mary,         7,         2,         4,          
     user2,      dude,      john,         6,         2,         4,          
     user3,    dudest,       rad,          ,          ,          ,          
     user4,     dudaa,       pad,         3,         3,         5,         9

【讨论】:

  • +1:如果你这样做"%-10s%s",那么它的格式会好很多。 更新它可能会留下尾随空格。
  • 是的,我用不同的 printf 格式将答案延迟了 5 分钟以上,最后我放弃了这个。
  • :) 我喜欢这个printf "%-s%s ", $i, (i&lt;n)?OFS:RS}' OFS=',' csv | column -t 虽然它需要一个额外的管道!
【解决方案2】:

Anubhava 的答案应该更快(因为它是 awk,而不是 bash)。我添加一个答案只是为了回答您关于如何将read 扩展到 n 列的问题。

n=5
while IFS=, read -a columns; do
    for i in ${!columns[@]}; do # * NOTE1
        [ "${columns[$i]}" ] || columns[$i]=$n
    done
    printf "%s" ${columns[0]}; printf ",%s" ${columns[@]:1} # * NOTE2
done < something.csv > newfile.csv && mv newfile.csv something.csv

注意1:如果条目为空,但存在占位符,请按原样使用 for 循环。
如果 csv 文件中的列数不固定(例如检查 user3 行),则将内部 for 循环更改为 for ((i=0;i&lt;$max_columns;i++)); do

注意 2:在 printf 命令中,如果需要,将 %s 更改为 %10s

【讨论】:

    猜你喜欢
    • 2017-07-21
    • 2021-03-21
    • 2016-08-12
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多