次の内容を含むCSVファイルのテキストを操作するコードを書きたいです。
71w - Rus,51200
71w - Phi,307200
71w - Ukr,307200
71w - Ukr,51200
71w - Mic,102400
71w - Mic,51200
71w - Jul,256000
71w - Jul,51200
71w - Pro,256000
71w - Uni,51200
71w - Ind,50176
71w - Ind,40960
71w - Sin,358400
71w - May,20480
71w - Tha,512000
71w - Tha,972800
71w - Bar,1280000
71w - Bar,102400
71w - Bar,2048000
71w - Upg,358400
71w - Leg,20480
71w - Res,153600
同じ値を持つ列を収集して、次のようにその行に配置したいと思います。
71w - Rus,51200
71w - Phi,307200
71w - Ukr,307200,51200
71w - Mic,102400,51200
71w - Jul,256000,51200
71w - Pro,256000
71w - Uni,51200
71w - Ind,50176,40960
71w - Sin,358400
71w - May,20480
71w - Tha,512000,972800
71w - Bar,1280000,102400,2048000
71w - Upg,358400
71w - Leg,20480
71w - Res,153600
ありがとうございます。
ベストアンサー1
これを行う良い方法は、連想配列またはハッシュを使用することです。各ハッシュのキーは最初のフィールドであり(より良い用語を使用するために「ids」と呼びます)、各キーに格納されている値はカンマ区切り値を含む文字列です。 ID リストまたは次を含む配列です。同じ内容。
奇妙な:
この awk バージョンは、配列の連想配列を扱うよりも (awk で) 簡単なので、カンマ区切り文字列を使用します。
#!/usr/bin/awk -f
BEGIN {
FS=" *, *";
OFS="";
}
{
key=$1; $1=""; $0=$0;
if (length(ids[key]) > 0) {
ids[key]=ids[key]","$0;
} else {
ids[key] = $0
};
}
END {
for (k in ids) {
print k "," ids[k]
}
}
Perlの配列ハッシュ(または「HoA」)操作は、文字列を連結するよりも難しくありません(そしてより便利で柔軟です)。
#!/usr/bin/perl -w
use strict;
my %ids = ();
while(<>) {
chomp;
my @F = split /\s*,\s*/;
push @{ $ids{$F[0]} }, $F[1];
};
END {
foreach my $key (keys %ids) {
print $key . ',' . join(",",@{ $ids{$key} }), "\n";
}
}
awk および perl バージョンの出力は同じです。
71w - Ukr,307200,51200
71w - Bar,1280000,102400,2048000
71w - Res,153600
71w - Upg,358400
71w - Sin,358400
71w - Mic,102400,51200
71w - May,20480
71w - Tha,512000,972800
71w - Jul,256000,51200
71w - Uni,51200
71w - Ind,50176,40960
71w - Pro,256000
71w - Rus,51200
71w - Leg,20480
71w - Phi,307200
注:awkおよびperlバージョンの出力は特別な順序ではなく、実行されるたびに異なる順序で表示されることがあります。これは、awkの「連想配列」とPerlの「ハッシュ」(同じものを指す2つの名前)が本質的に順序がないためです。
sort
必要に応じて出力をパイプできます。または、Perlでは次のものを使用できます。
foreach my $key (sort keys %ids) {
変える:
foreach my $key (keys %ids) {
また、各IDの個々の値を配列に格納するため、Perlでも値を簡単に並べ替えることができます。たとえば、END
Perlバージョンのブロック全体を次のように置き換えます。
END {
foreach my $key (sort keys %ids) {
print $key . ',' . join(",",sort @{ $ids{$key} }), "\n";
}
}
出力は次のとおりです。
71w - Bar,102400,1280000,2048000
71w - Ind,40960,50176
71w - Jul,256000,51200
71w - Leg,20480
71w - May,20480
71w - Mic,102400,51200
71w - Phi,307200
71w - Pro,256000
71w - Res,153600
71w - Rus,51200
71w - Sin,358400
71w - Tha,512000,972800
71w - Ukr,307200,51200
71w - Uni,51200
71w - Upg,358400