如何使用shell脚本有效地处理大型csv文件,以获得比后续脚本更好的性能?

时间:2015-06-24 12:11:41

标签: bash shell csv

我有一个包含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

但它花了很多时间。

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

1 个答案:

答案 0 :(得分:2)

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

执行此操作
BEGIN{FS=OFS=","}

工作原理:

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