1

我有一个包含很多列的大 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 标头),我相信所有带有回声和削减的子外壳都会减慢速度,所以“哈希表”真的没有多大用处......

谁能让这一切快点?

4

2 回答 2

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 中有一些标题行,你当然不能用这个函数来转换它们。

于 2013-06-21T22:14:26.157 回答
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

跳过标题。

于 2013-06-21T23:08:37.250 回答