2009-10-08 6 views
0

파일의 필드를 기반으로 분할하고 싶은 CSV 파일이 있습니다. 기본적으로 GVA와 HBVL이라는 두 가지 브랜드가있을 수 있습니다. 데이터베이스로 가져 오기 전에 파일을 각 브랜드의 파일로 분할하고 싶습니다. CSV 파일sed를 사용하여 동적으로 파일 이름 생성

샘플 문제의

"D509379D5055821451C3695A3752DCCD",'1900-01-01 01:00:00',"M","1740","GVA",'2009-07-01 13:25:00',0 
"159A58BE41012787D531C7157F688D86",'1900-01-01 00:00:00',"V","1880","GVA",'2008-06-06 11:21:00',0 
"D0BB5C058794BBE4478DDA536D1E4872",'1900-01-01 00:00:00',"M","9270","GVA",'2007-09-18 13:21:00',0 
"BCC7096803E5E60E05DC12FB9951E0CF",'1900-01-01 00:00:00',"M","3500","HBVL",'2007-09-18 13:21:00',1 
"7F85FCE6F13775A8A3054E3438B81599",'1900-01-01 00:00:00',"M","3970","HBVL",'2007-09-18 13:20:00',0 

일부는 파일의 크기 파일. 그것은 약 39mb입니다. 이것에 나의 원래 시도는 이것 같이 보았다 :

while read line ; do 

    name=`echo $line | sed -n 's/\(.*\)"\(GVA\|HBVL\)",\(.*\)$/\2/ p' | tr [:upper:] [:lower:] ` 
    info=`echo $line | sed -n 's/\(.*\)"\(GVA\|HBVL\)",\(.*\)$/\1\3/ p'` 

    echo "${info}" >> ${BASEDIR}/${today}/${name}.txt 

done < ${file} 

후에 대략 2.5 시간, 단지 파일의 대략 1/2 가공되었다. 나는 잠재적으로 250 메가 바이트까지의 크기가 될 수있는 또 다른 파일을 가지고 있으며 그것이 얼마나 오래 걸릴지 상상할 수 없다.

내가하고 싶은 것은 라인 밖으로 브랜드를 꺼내 브랜드 이름을 따서 파일 이름에 써 넣는 것입니다. 브랜드를 제거 할 수는 있지만 지금은 파일을 만드는 방법을 사용하지 않습니다. 나는 sed에서 시작했지만 더 적절하다면 다른 언어를 사용하는 것이 아닙니다.

+1

당신은 또한 나오지도 같은 외부 명령어를 사용하거나 루프에서 함께 그럴 필요 특히 경우, 배쉬의 동안 큰 파일을 읽을 라인 구조를 읽을 사용하지 않습니다. 엄청나게 처리 속도가 느려집니다. awk – ghostdog74

답변

3

한 줄에 여러 개의 명령이있는 원래 while 루프는 DIRE입니다!

sed -e '/"GVA"/w gva.file' -e '/"HBVL"/w hbvl.file' -n $file 

sed 스크립트는 말한다 다음 GVA 태그를 일치

  • 기록 라인이
  • 을 hbvl.file하는 HBVL 태그를 일치하지 않는
  • 기록 라인을 gva.file하기 다른 것을 인쇄하십시오 ('-n')

다른 버전의 sed은 다른 수의 보조 파일을 처리 할 수 ​​있습니다. 한 번에 20 개의 출력 파일을 필요로하는 경우 다른 기술을 조사해야 할 수도 있습니다 (단, 시스템의 한계를 테스트 할 수 있음). 파일이 정렬되어 모든 GVA 레코드가 함께 나타나고 모든 HBVL 레코드가 표시되면 csplit을 사용할 수 있습니다. 또는 Perl과 같은 스크립팅 언어가 더 많은 것을 처리 할 수 ​​있습니다. 프로세스에 허용 된 파일 디스크립터 수를 초과하면 데이터 파일을 한 번에 나누기가 어려워집니다.

+1

과 같이 파일을 내부적으로 파싱하는 도구를 사용하십시오. 참고 :이 기술을 사용하여 브랜드 필드를 제거 할 수도 있습니다 :'sed -n -e '/ "GVA"/ s/\ (. * \) "\ (GVA \) ", \ (. * \) $/\ 1 \ 3/w gva.file '-e'... ' –

+0

나는 내가 생각했던 것들을 알고 있었다. 나는 이처럼 늦은 시간에 문제를 해결하려고해서는 안됩니다. – cabuki

1
grep '"GVA"' $file >GVA.txt 
grep '"HVBL"' $file >HVBL.txt 
+0

파일 당 두 개의 명령 - 한 줄에 여러 개가 있지만 여전히 느립니다 ... –

+0

가장 빠른 해결책은 아니지만 충분히 가까울 수 있습니다. 확실히 이해하기 쉽습니다. –

+0

파일이 매우 큰 경우 grep을 사용하여 파일을 2 번 반복합니다. 파일을 한 번 살펴보고 필요한 것을 얻는 것이 좋습니다. – ghostdog74

1
# awk -F"," '{o=$5;gsub(/\"/,"",o);print $0 > o}' OFS="," file 
# more GVA 
"D509379D5055821451C3695A3752DCCD",'1900-01-01 01:00:00',"M","1740","GVA",'2009-07-01 13:25:00',0 
"159A58BE41012787D531C7157F688D86",'1900-01-01 00:00:00',"V","1880","GVA",'2008-06-06 11:21:00',0 
"D0BB5C058794BBE4478DDA536D1E4872",'1900-01-01 00:00:00',"M","9270","GVA",'2007-09-18 13:21:00',0 
# more HBVL 
"BCC7096803E5E60E05DC12FB9951E0CF",'1900-01-01 00:00:00',"M","3500","HBVL",'2007-09-18 13:21:00',1 
"7F85FCE6F13775A8A3054E3438B81599",'1900-01-01 00:00:00',"M","3970","HBVL",'2007-09-18 13:20:00',0 
+0

... 인용 된 리터럴에 쉼표가 없기를 바랍니다 ... –

관련 문제