2013-08-17 5 views
1

CSV 파일 내에 filenamecolumn name의 두 가지 인수를 사용하는 서브 루틴을 작성하려고합니다. 서브 루틴은 두 번째 인수 (열 이름)를 검색하고 CSV 파일에서 해당 열을 제거한 다음 인수가 제거 된 CSV 파일을 반환합니다.CSV 파일에서 열을 검색하고 제거합니다.

이 하위의 첫 번째 절반 (파일 열기, 헤더 및 값 검색)을 얻은 것 같은 느낌이 들지만 CSV 파일에서 사용자가 검색하는 방법을 찾지 못하는 것 같습니다. 전체 열을 입력하고 삭제합니다. 어떤 아이디어? 여기 내가 지금까지 가지고있는 것이있다.

sub remove_columns { 
    my @Para = @_; 
    my $args = @Para; 
    die "Insufficent arguments\n" if ($nargs < 2); 

    open file, $file 
    $header = <file>; 
    chomp $header; 

    my @hdr = split ',',$header; 

    while (my $line = <file>){ 
    chomp $line; 
    my @vals = split ',',$line; 

    #hash that will allow me to access column name and values quickly 
    my %h; 

    for (my $i=0; $i<=$#hdr;$i++){ 
     $h{$hdr[$i]}=$i; 
    } 
    .... 
} 

여기서 검색 및 제거가 수행됩니다. 나는 이것을 어떻게 생각하는지에 대해 생각 해왔다. 내가 수정할 것 인 CSV 파일은 엄청날 것이기 때문에 속도가 중요한 요소이지만이 문제를 해결할 좋은 방법을 생각할 수는 없다. 나는 Perl에 익숙하지 않아 조금 어려움을 겪고있다.

답변

1

여기에 몇 가지 힌트가 있습니다. 속도가 문제이기 때문에

splice @array,$index,1 ; 

, 당신은 아마도에 시작에서 열 번호의 배열 한 후 루프를 구성 할 :

배열 사용의 위치 $index에서 배열의 요소를 제거하려면 어레이의 요소들이

for my $index (@indices) { 
    splice @array,$index,1 ; 
} 

( 이 방법 for (my $i=0; $i<=$#hdr;$i++) 형 루프 펄보다 더 관용적이다)

또 다른 고려 사항 - CSV 형식은 놀라 울 정도로 복잡합니다. 데이터가 " " 같은

같은
1,"column with a , in it" 

,와 데이터가있을 수 있습니다 나는 Text::CSV

1

당신은 아마 Text::CSV

의 방향으로 보일 것입니다 아니면 이런 일을 할 수있는 같은 것을 사용하는 것이 좋습니다 것입니다 :

my $colnum; 
my @columns = split(/,/, <$file>); 
for(my $i = 0; $i < scalar(@columns); $i++) { 
    if($columns[$i] =~ /^$unwanted_column_name$/) { 
     $colnum = $i; 
     last; 
    }; 
}; 

while(<$file>) { 
    my @row = split(/,/, $_); 
    splice(@row, $colnum, 1); 
    #do something with resulting array @row 
}; 

사이드 노트 : 사용하려면 strictwarnings을 사용해야합니다.

split(/,/, <$file>); 

모든 CSV 파일

1

배열에서 약간의 열을 제거하는 방법 우아한 방법이 작동하지 않습니다.내가 @headers에 배열 @cols의 제거에 열 및 헤더가있는 경우 나 인덱스의 배열을 보존 할 수 있습니다 :

my %to_delete; 
@to_delete{@cols} =(); 
my @idxs = grep !exists $to_delete{$headers[$_]}, 0 .. $#headers; 

을 그 다음 읽기의 새로운 헤더

@headers[@idxs] 

또한 새 행을 쉽게 만들 수 열

@columns[@idxs] 

동일한 방법을 사용하여 배열을 다시 배열 할 수 있습니다. 그것은 매우 빠르고 관용적 인 Perl 방식으로 이런 종류의 작업을 수행하는 방법입니다.

관련 문제