我有一个包含大量列的大型CSV文件(几个100 MB):
1;18Jun2013;23:58:58;;;l;o;t;s;;;;o;f;;;;;o;t;h;e;r;;;;;c;o;l;u;m;n;s;;;;;
您会看到第二列是我希望格式为%Y-%m-%d的日期,以便在数据库中轻松插入和排序。我相信转换原始数据更容易,更快,而不是以后在数据库中转换。
主脚本使用bash。现在我已经按照以下步骤进行了转换:
sed -n '2,$p' $TMPF | while read line; do
begin=$(echo "$line" | cut -d\; -f1)
origdate=$(echo "$line" | cut -d\; -f2)
#cache date translations, hash table for the poor
eval origdateh=h$origdate
if [ "x${!origdateh}" = "x" ]; then
# not cached till now, need to call date, then store
datex=$(date -d "$origdate" +%Y-%m-%d)
eval h$origdate="$datex"
else
# cache hit
datex=$(eval echo \$h$origdate)
fi
end=$(echo "$line" | cut -d\; -f3-)
echo "$begin;$datex;$end" >> $TMPF2
done
我使用sed从第二行开始(第一行包含CSV标题)并且我相信所有带有回声和剪切的子shell减慢了速度,所以“哈希表”真的没用多少......
谁可以让这个快点?
答案 0 :(得分:3)
不要使用bash脚本,而是使用Python脚本。至少,这将更具可读性/可维护性,并且可能更有效。
示例代码看起来像这样(未经测试):
# file: converter.py
import datetime
def convert_line(line):
# split line on ';'
line = line.split(';')
# get the date part (second column)
# parse date from string
date = datetime.date.strptime(line[1], '%d%a%Y')
# convert to desired format
# replace item in line
line[1] = date.strftime('%Y-%m-%d')
# return converted line
return ';'.join(line)
while True:
print convert_line(raw_input())
现在你做的就是:
cat file.csv | python converter.py > file_converted.csv
替代实施:
# file: converter_2.py
import datetime
def convert_line(line):
# split line on ';'
line = line.split(';')
# get the date part (second column)
# parse date from string
date = datetime.date.strptime(line[1], '%d%a%Y')
# convert to desired format
# replace item in line
line[1] = date.strftime('%Y-%m-%d')
# return converted line
return ';'.join(line)
with open('file.csv') as infile, open('file_converted.csv', 'w+') as outfile:
outfile.writelines(convert_line(line) for line in infile)
使用示例:
python converter_2.py
如果你的csv中有一些标题行,你当然不能用这个函数转换它们。
答案 1 :(得分:1)
谢谢,我尝试了第一个例子,当从bash脚本中调用时,以下似乎工作正常。
# file: converter.py
import datetime
def convert_line(line):
# split line on ';'
line = line.split(';')
# get the date part (second column)
# parse date from string
date = datetime.datetime.strptime(line[1], '%d%b%Y')
# convert to desired format
# replace item in line
line[1] = date.strftime('%Y-%m-%d')
# return converted line
return ';'.join(line)
while True:
try:
print convert_line(raw_input())
except (EOFError):
break
使用
tail +2 FILE | python csvconvert.py > xxx
跳过标题。