LinuxコマンドラインでCSVファイルを解析するにはどうすればよいですか?
次のようなことを行うには:
csvparse -c 2,5,6 filename
すべての行の列2、5、6からフィールドを抽出します。
Csvファイル形式を処理できる必要があります。 http://tools.ietf.org/html/rfc418 これは、フィールドを引用し、必要に応じて内部引用符をエスケープすることを意味します、したがって3つのフィールドを持つ行の例:
field1,"field, number ""2"", has inner quotes and a comma",field3
上記の行のフィールド2をリクエストすると、次のようになります:
field, number "2", has inner quotes and a comma
この問題には、Perl、Awkなどの多数のソリューションがあることを感謝していますが、他のスクリプト環境を呼び出したり、追加のコードを記述したりする必要のないネイティブのbashコマンドラインツールが欲しいです!.
私のFOSS CSVストリームエディター CSVfix はまさにあなたが望むことをします。 Windows用のバイナリインストーラーと、UNIX/Linux用のコンパイル可能なバージョン(メイクファイル経由)があります。
csvtoolは本当に良いです。 Debian/Ubuntu(apt-get install csvtool
)。例:
csvtool namedcol Account,Cost input.csv > output.csv
使い方のヒントについては、 CSVToolのマニュアルページ を参照してください。
コメントで@Jonathanが示唆したように、コマンドラインツールcsvfilterを提供するpythonのモジュールがあります。カットのように機能しますが、CSV列の引用を適切に処理します。
csvfilter -f 1,3,5 in.csv > out.csv
python(あるべき))がある場合、次のように簡単にインストールできます。
pip install csvfilter
csvkit が有用であることがわかりました。これはpythoncsvモジュールに基づいており、複雑なcsvファイルを解析するための非常に多くのオプション。
少し遅いようですが。 5列の7GB CSVから1つのフィールドを抽出すると、4MB/s(100%CPU)を取得します。
file.csv
から4番目の列を抽出するには
csvcut -c 4 file.csv
crush-tools を試してください。これらは区切りデータの操作に優れています。まさにあなたが探しているもののように聞こえます。
csvprintf と呼ばれるこれらのツールの1つ(UNIXのみ)も作成しました。また、オンライン形式でXMLに変換することもできます。
私の直感的な反応は、Pythonのcsvモジュールの周りにスクリプトラッパーを書くことです(まだそのようなものがない場合)。
Pythonのcsv
モジュールの超軽量ラッパーについては、 pluckr をご覧ください。
これはawkの仕事のように思えます。
ほとんどの場合、特定のニーズに合わせて独自のスクリプトを作成する必要がありますが、 this サイトには、これを実行する方法についての対話があります。
また、カットユーティリティを使用してフィールドを削除することもできます。
何かのようなもの:
cut -f 2,5,6 -d , filename
-f引数は必要なフィールドで、-dは必要なデリミタです。その後、これらの結果を並べ替えたり、一意の結果を見つけたり、他のbashユーティリティを使用したりできます。コマンドラインからのCSVファイルの操作についてのクールなビデオ こちら があります。ほんの一分ほど、見てみます。
ただし、カットユーティリティをawkでグループ化し、使用したくないと思います。ただし、ネイティブのbashコマンドの意味が正確にはわからないので、引き続き提案します。
ffe
はもう1つの優れたツールです。ほとんどの重要なタスクのために、構成ファイルを作成する必要があります。利点は、非常に柔軟性があり、他のツールではできないあらゆる種類の構造、ロジック、およびフォーマットを処理できることです。
クイックジョブにはcsvtool
を使用し、複雑なジョブや頻繁に繰り返す必要があるジョブにはffe
を使用するのが好きです。
Perlスクリプト(Text :: CSV_XSが必要):
#!/usr/bin/Perl
use strict;
use warnings;
use Getopt::Long;
my @opt_columns;
GetOptions("column=i@" => \@opt_columns)
or die "Failed parsing options\n";
die "Must give at least one --column\n" if int(@opt_columns) == 0;
@opt_columns = map { $_-1 } @opt_columns; # convert 1-based to 0-based
use Text::CSV_XS;
my $csv = Text::CSV_XS->new ( { binary => 1 } );
open(my $stdin, "<-") or die "Couldn't open stdin\n";
open(my $stdout, ">-") or die "Couldn't open stdout\n";
while (my $row = $csv->getline($stdin)) {
my @nrow = @{$row}[@opt_columns];
$csv->print($stdout, \@nrow);
print "\n";
}
ファイルに入れるcsvcut.pl
。
列3および4のみを取得する例:
cat foo.csv | ./csvcut.pl --c 3 --c 4
これは、引用を必要とする列のみを引用するため、入力列に「引用符付き」の「Bar」がある場合は、引用符なしのBarが表示されます。
簡単なグーグルで awk script が明らかになり、csvファイルを処理しているようです。