2013-06-21 3 views
1
에서 변환을 수행

나는 열이 많은 큰 CSV 파일 (여러 100 개 매크로 블럭)이 있습니다 구문 분석 CSV 파일 및 Linux

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 

내가 (1 라인은 CSV 헤더를 포함) 두 번째 줄과 시작 sed를 사용하고 난이 에코 및 절단 속도가 느린 것을 아래로 모든 서브 쉘을 생각 : 지금 나는 변환을 위해 다음과 같이 진행했습니다 그래서 "해시 테이블"은 실제로 많이 사용되지 않습니다 ...

누가 이것을 빠르게 할 수 있습니까?

+0

'누가 빨리 할 수 ​​있습니까?': 전용 CSV 파서를 사용하여 나만 볼 수 있습니다. – anubhava

+0

이 작업은 bash에서 수행해야합니까? 셸보다 더 나은 배열/분할/조인 구현을 사용한다면 (루비/펄/파이썬을 생각하고있다.) 상당한 속도 향상을 얻을 수있다. – Joe

답변

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에 헤더 행이있는 경우이 기능으로 변환하지 않아야합니다.

+0

그 속도는 내 마음에 든다. (몇 분 안에 700MB 파일). – Marki

1

감사합니다. 첫 번째 예제를 시도해 보았습니다. 다음은 bash 스크립트에서 호출 할 때 잘 작동하는 것 같습니다. 사용

tail +2 FILE | python csvconvert.py > xxx 

# 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 

헤더를 건너 뜁니다.