2013-11-25 5 views
4

12 개의 열이있는 쉼표로 구분 된 파일이 있습니다.쉼표로 구분 된 파일에서 여분의 쉼표 제거

다섯 번째와 여섯 번째 열 (다섯 번째와 여섯 번째 열의 텍스트는 동일하지만 여분의 쉼표가있을 수 있음)에는 쉼표가 추가로 포함되어있어 문제가 있습니다.

2011,123456,1234567,12345678,Hey There,How are you,Hey There,How are you,882864309037,ABC ABCD,LABACD,1.00000000,80.2500000,One Two 

위의 예에서 "안녕하세요, 어떻게 지내세요?"는 쉼표가 없어야합니다.

5 번째 및 6 번째 열에 쉼표를 추가로 제거해야합니다. 당신은 항상 5 쉼표를 제거하려면

+0

4 번째 및 7 번째 열에는 항상 숫자가 포함됩니까? –

+2

가능하면 쉼표가있는 열에 캡슐화를 사용하여 csv 파일을 올바르게 다시 요청하거나 재생성하는 것이 가장 좋습니다. 예 : '2011,123456,1234567,12345678, "안녕하세요, 어떻게 지내세요?", "안녕하세요, 어떻게 지내세요?", 882864309037, ABC ABCD, LABACD, 1.00000000,80.2500000, One Two' – AeroX

답변

4

,

sed 's/,//5' input.txt 

을 시도하지만 당신은 그것을 수도 여분의 쉼표를 가지고 말. 여분의 쉼표가 있는지 여부를 확인하는 방법을 논리로 제공해야합니다.

쉼표 수를 알고있는 경우 을 사용할 수 있습니다. 이것은 꽤 운동을 것으로 입증되었습니다, 나는 다른 사람이 더 우아한 해결책 올 것이다 확신하지만, 어쨌든 내를 공유 할 수 있습니다 :

awk -f script.awk input.txt 

script.awk로 :

BEGIN{ 
    FS="," 
} 
NF<=12{ 
    print $0 
} 
NF>12{ 
    for (i=1; i<=4; i++) printf $i FS 
    for (j=0; j<2; j++){ 
     for (i=0; i<=(NF-12)/2; i++){ 
      printf $(i+5) 
      if (i<(NF-12)/2) printf "_" 
      else printf FS 
     } 
    } 
    for (i=NF-5; i<=NF; i++) printf $i FS 
    printf "n" 
} 

먼저 필드 구분자를 ,으로 설정합니다. 12 필드보다 작거나 같으면 모든 것이 좋으며 단순히 전체 줄을 인쇄합니다. 필드가 12 개 이상인 경우 처음 4 개의 필드를 다시 인쇄하고 (필드 구분 기호로 다시) 필드 5 (필드 6)를 두 번 인쇄하지만 ,을 인쇄하는 대신 _으로 바꿉니다. 결국 나머지 필드를 출력합니다.

내가 말했듯이, 아마도 이것에 대한보다 우아한 해결책이있을 것입니다. 다른 사람들이 무엇을 생각해 내는지 궁금합니다.

+0

각 행에 쉼표가 11 개씩 있어야합니다. (12 개의 열이 있습니다), 5 번째와 6 번째 열에는 쉼표가 추가로 있습니다. – Stu

2

다른 모든 필드가 디지털 인 경우 해당 조건에 따라 유용한 쉼표를 저장하려고 할 수 있습니다.

sed -r 's/(,)[0-9]/;/g' a | sed -r 's/[0-9](,)/;/g' | sed -r 's/,//g' | awk -F\; '{ print $1 "," $2 "," $3 "," $4 "," substr($5, 0, length($5)/2) "," substr($5, length($5)/2 +1, length($5)/2) "," $6 "," $7}' 
2011,23456,234567,234567,Hey ThereHow are you,Hey ThereHow are you,8286430903, 
1

Text::CSV_XS 모듈을 시도 할 수

#!/usr/bin/env perl 

use warnings; 
use strict; 
use Text::CSV_XS; 

my (@columns); 

open my $fh, '<', shift or die; 

my $csv = Text::CSV_XS->new or die; 
while (my $row = $csv->getline($fh)) { 
    undef @columns; 
    if (@$row <= 12) { 
     @columns = @$row; 
     next; 
    } 

    my $extra_columns = (@$row - 12)/2; 
    my $post_columns_index = 4 + 2 * $extra_columns * 2; 
    @columns = ( 
     @$row[0..3], 
     (join('', @$row[4..(4+$extra_columns)])) x 2, 
     @$row[$post_columns_index..$#$row] 
    ); 
} 
continue { 
    $csv->print(\*STDOUT, \@columns); 
    printf "\n"; 
} 

첫 번째는 추가 쉼표를 갖는 세 개의 라인, 입력 파일 (infile)을 가정은 두 번째 추가 두 갖는다 쉼표 세번째는 올바른 :

,369 :

2011,123456,1234567,12345678,Hey There,How are you,Hey There,How are you,882864309037,ABC ABCD,LABACD,1.00000000,80.2500000,One Two 
2011,123456,1234567,12345678,Hey There,How are you,now,Hey There,How are you,now,882864309037,ABC ABCD,LABACD,1.00000000,80.2500000,One Two 
2011,123456,1234567,12345678,Hey There:How are you,Hey There:How are you,882864309037,ABC ABCD,LABACD,1.00000000,80.2500000,One Two 

같이 스크립트를 실행

perl script.pl infile 

수익률 그건 : 그것은 어떤 따옴표를 추가하지만 그것이 csv 사양에 올바른 기초를 쉽게

2011,123456,1234567,12345678,"Hey ThereHow are you","Hey ThereHow are you",882864309037,"ABC ABCD",LABACD,1.00000000,80.2500000,"One Two" 
2011,123456,1234567,12345678,"Hey ThereHow are younow","Hey ThereHow are younow",LABACD,1.00000000,80.2500000,"One Two" 
2011,123456,1234567,12345678,"Hey There:How are you","Hey There:How are you",882864309037,"ABC ABCD",LABACD,1.00000000,80.2500000,"One Two" 

하는 것으로 이전 상태 것으로 처리합니다.

관련 문제