Text-Processing
文本操作 - 根據值將列轉置為行
我想編寫一個程式碼來操作我的 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
謝謝你。
一個很好的方法是使用關聯數組或雜湊。每個雜湊的鍵是第一個欄位(我將它們稱為“ids”,因為需要更好的術語),並且為每個鍵儲存的值將是一個字元串,其中包含一個逗號分隔的值列表id,或包含相同的數組。
awk:
這個 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 “雜湊”(同一事物的兩個名稱)本質上是無序的。
如果需要,您可以將輸出通過管道傳輸到
sort
。或者,在 perl 中,您可以使用:foreach my $key (sort keys %ids) {
代替:
foreach my $key (keys %ids) {
另外 - 因為我們將每個 id 的單獨值儲存在一個數組中,所以在 perl 中也很容易對這些值進行排序。例如,將 perl 版本中的整個
END
塊替換為: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