我想编写一个脚本,将多个 .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
下面是一个 perl 脚本,它读取命令行上指定的每个文件的每一行并将其附加到数组 ( @csv
) 中的元素。当没有更多输入时,它会打印出 的每个元素@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
为每个丢失的文件添加正确的空字段数量来处理不同长度的文件线或至少检测不同的长度并退出错误),但如果需要更复杂的合并,这是一个合理的起点。
顺便说一句,这使用了一种非常简单的算法,并一次性将所有输入文件的全部内容存储在内存中(在 中@csv
)。对于现代系统上每个文件大小高达几 MB 的文件来说,这并非不合理。但是,如果您正在处理巨大的 .csv 文件,更好的算法将是:
- 打开所有输入文件,尽管仍有输入要读取:
- 从每个文件中读取一行
- 追加行(按 @ARGV 顺序)
- 打印附加行