【问题标题】:How to process large csv files efficiently using shell script, to get better performance than that for following script?如何使用 shell 脚本有效地处理大型 csv 文件,以获得比以下脚本更好的性能?
【发布时间】:2015-06-24 12:11:41
【问题描述】:

我有一个包含 5 列的大型 csv 文件 input_file。我想对第二列做两件事:

(1) 删除最后一个字符 (2) 附加前导和尾随单引号

以下是来自input_file.dat 的示例行

420374,2014-04-06T18:44:58.314Z,214537888,12462,1
420374,2014-04-06T18:44:58.325Z,214537850,10471,1
281626,2014-04-06T09:40:13.032Z,214535653,1883,1

示例输出如下所示:

420374,'2014-04-06T18:44:58.314',214537888,12462,1
420374,'2014-04-06T18:44:58.325',214537850,10471,1
281626,'2014-04-06T09:40:13.032',214535653,1883,1

我已经编写了以下代码来做同样的事情。

#!/bin/sh
inputfilename=input_file.dat
outputfilename=output_file.dat
count=1

while read line
do
  echo $count
  count=$((count + 1))
  v1=$(echo $line | cut -d ',' -f1)
  v2=$(echo $line | cut -d ',' -f2)
  v3=$(echo $line | cut -d ',' -f3)
  v4=$(echo $line | cut -d ',' -f4)
  v5=$(echo $line | cut -d ',' -f5)
  v2len=${#v2}
  v2len=$((v2len -1))
  newv2=${v2:0:$v2len}
  newv2="'$newv2'"
  row=$v1,$newv2,$v3,$v4,$v5
  echo $row >> $outputfilename
done < $inputfilename

但这需要很多时间。

有没有有效的方法来实现这一点?

【问题讨论】:

  • 使用 awk 或 sed 进行此类工作。

标签: bash shell csv


【解决方案1】:

您可以通过awk 做到这一点

awk -v q="'" 'BEGIN{FS=OFS=","} {$2=q substr($2,1,length($2)-1) q}1' input_file.dat

它是如何工作的:

  • BEGIN{FS=OFS=","} :设置输入输出字段分隔符(FSOFS)为,
  • -v q="'" :为变量 q 分配一个文字单引号(以避免在 awk 表达式中进行复杂的转义)
  • {$2=q substr($2,1,length($2)-1) q} :将第二个字段 ($2) 替换为单引号 (q),后跟不带最后一个字符的第二个字段的值 (substr(string, start, length)) 并附加文字单引号 (q)最后。
  • 1 :只需调用默认操作,即 print 当前(已编辑)行。

【讨论】:

  • 你还需要设置OFS,否则输出不会被逗号分隔。剩下的,+1,干得好!
  • @fedorqui 哦,你是对的,不错的收获!我会尽快更新的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-05
  • 2017-11-12
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 2011-01-28
  • 2013-01-16
相关资源
最近更新 更多