【问题标题】:Text processing on CSV fileCSV文件的文本处理
【发布时间】:2015-09-13 02:54:36
【问题描述】:

我正在处理一个格式如下的文件:

"1999-01-04";1391.12;3034.53;66.515625;86.2;441.39
"1999-01-05";1404.86;3072.41;66.3125;86.17;440.63
"1999-01-06";1435.12;3156.59;66.4375;86.32;441

有时,有些值没有小数点(例如 441 而不是 441.0),我需要小数点。如何编写一个脚本,使所有整数都添加 .0 以使其变为浮点数?

【问题讨论】:

  • 我知道,这不是问题的答案,因为您要求基于 bash 的解决方案。无论如何,你为什么不使用python的csv模块呢?
  • 如果您知道输入字段的数量是六个,您可以瞄准低点并使用awk -F\; '{ printf "%s;%s;%s;%s;%s;%.2f\n", $1, $2, $3, $4, $5, $6 }'
  • 基本上有两个原因:1)我对 Python 知之甚少,2)我知道的一点点(如果准确的话)告诉我 bash 比 Python 快得多。因此,我对学习如何在 bash 中执行此操作更感兴趣,这样我就可以使用这些知识以更低的成本处理大文件。有意义吗?
  • @Alexandre Python 在文本处理方面明显快于 bash,尽管 awk 和 sed 通常都比 python 快(对于文本处理)

标签: bash shell csv awk sed


【解决方案1】:

将此awk 脚本保存为awk.src

BEGIN {
  FS=";"
}
#
## MAIN Block
#
{
  printf $1; printf FS;
  for (i=2;i<=NF;i++) {
    if ($i !~ "\\.") {
      printf "%.1f", $i;
    }
    else { printf $i; }
    if (i!=NF) {
      printf FS;
    }
    else { printf "\n"; }
  }
}

试试看:

$ awk -f awk.src < sample.txt 
"1999-01-04";1391.12;3034.53;66.515625;86.2;441.39
"1999-01-05";1404.86;3072.41;66.3125;86.17;440.63
"1999-01-06";1435.12;3156.59;66.4375;86.32;441.0

【讨论】:

    【解决方案2】:

    使用 sed

    sed 's/\(;[^\.]*\)\(;\|$\)/\1.00\2/g' file
    

    只是一个简单的替换正则表达式。

    "1999-01-04";1391.12;3034.53;66.515625;86.2;441.39
    "1999-01-05";1404.86;3072.41;66.3125;86.17;440.63
    "1999-01-06";1435.12;3156.59;66.4375;86.32;441.00
    

    【讨论】:

    • ^1 但恕我直言,如果您添加 -r 并摆脱所有转义以激活 ERE 元字符,则更清楚:sed -r 's/(;[^\.]*)(;|$)/\1.00\2/g' file
    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多