여러 .csv 파일의 내용을 하나의 .csv 파일로 병합하는 스크립트를 작성하고 싶습니다. 즉, 다른 모든 파일의 열을 첫 번째 파일의 열에 추가합니다. 이 작업을 수행하기 위해 "for" 루프를 사용해 보았으나 계속할 수 없습니다.
Linux에서 이 작업을 수행하는 방법을 아는 사람이 있습니까?
답변1
이를 달성하는 가장 쉬운 방법은 다음 명령을 입력하는 것입니다.
cat *csv > combined.csv
이 파일에는 언급한 모든 csv 파일의 내용이 포함됩니다.
답변2
awk '(NR == 1) || (FNR > 1)' *.csv > 1000Plus5years_companies_data.csv
답변3
사용paste
paste -d ',' file1.csv file2.csv ... fileN.csv
답변4
@csv
다음은 명령줄에 지정된 각 파일의 각 줄을 읽고 이를 배열( )의 요소 에 추가하는 Perl 스크립트입니다 . 더 이상 입력이 없으면 각 요소를 인쇄합니다 @csv
.
파일은 .csv
명령줄에 나열된 순서대로 추가됩니다.
경고하다: 이 스크립트는 다음을 가정합니다.모든 입력 파일의 줄 수는 동일합니다.. 파일의 행 수가 다른 파일과 다른 경우 출력을 사용하지 못할 수 있습니다.
#!/usr/bin/perl
use strict;
my @csv=();
foreach (@ARGV) {
my $linenum=0;
open(F,"<",$_) or die "couldn't open $_ for read: $!\n";
while (<F>) {
chomp;
$csv[$linenum++] .= "," . $_;
};
close(F);
};
foreach (@csv) {
s/^,//; # strip leading comma from line
print $_,"\n";
};
다음 입력 파일이 주어지면:
==> 1.csv <==
1,2,3,4
1,2,3,4
1,2,3,4
1,2,3,4
==> 2.csv <==
5,6,7,8
5,6,7,8
5,6,7,8
5,6,7,8
==> 3.csv <==
9,10,11,12
9,10,11,12
9,10,11,12
9,10,11,12
다음과 같은 출력이 생성됩니다.
$ ./mergecsv.pl *.csv
1,2,3,4,5,6,7,8,9,10,11,12
1,2,3,4,5,6,7,8,9,10,11,12
1,2,3,4,5,6,7,8,9,10,11,12
1,2,3,4,5,6,7,8,9,10,11,12
자, 이제 여기까지 읽었으므로 이것이 하지 않는 일을 하지 paste -d, *.csv
않는다는 것을 인정해야 할 때입니다. 그렇다면 굳이 Perl을 사용하는 이유는 무엇입니까? paste
매우 융통성이 없습니다. 데이터가 작업에 완벽하게 적합하다면 paste
괜찮습니다. 작업에 완벽하고 매우 빠릅니다. 그렇지 않다면 그것은 당신에게 전혀 쓸모가 없습니다.
이와 같은 Perl 스크립트는 여러 가지 방법으로 개선될 수 있습니다(예: @csv
파일당 필드 수를 계산하고 누락된 각 파일에 대해 올바른 수의 빈 필드를 추가하거나 적어도 다른 길이 및 종료 오류를 감지하여 다양한 길이의 파일 행을 처리). 그러나 더 복잡한 병합이 필요한 경우 이것이 합리적인 출발점이 됩니다.
그런데 이것은 매우 간단한 알고리즘을 사용하고 모든 입력 파일의 전체 내용을 메모리(in @csv
)에 한 번에 저장합니다. 크기가 각각 최대 수 MB에 달하는 최신 시스템의 파일에 대해서는 이는 무리한 일이 아닙니다. 그러나 대용량 .csv 파일을 처리하는 경우 더 나은 알고리즘은 다음과 같습니다.
- 읽을 입력이 아직 남아 있지만 모든 입력 파일을 엽니다.
- 각 파일에서 한 줄 읽기
- 행 추가(@ARGV 순서)
- 추가 줄 인쇄