一意の値を計算し、結果の値を新しい列として追加します。

一意の値を計算し、結果の値を新しい列として追加します。

大容量のcsvファイルがあり、簡単なランキングを作成したいと思います。

$ cat file.csv
2022-12-01     RED     1     
2022-12-01     RED     1     
2022-12-01     RED     2     
2022-12-01     RED     2     
2022-12-01     RED     2     
2022-12-01     YELLOW     1     
2022-12-01     YELLOW     1     
2022-12-01     YELLOW     2     
2022-12-01     YELLOW     2     
2022-12-01     YELLOW     2     
$ sort file.csv | uniq -c | sort -nr > file_sort.csv
$ cat file_sort.csv 
3 2022-12-01     RED     2     
3 2022-12-01     YELLOW     2     
2 2022-12-01     RED     1     
2 2022-12-01     YELLOW     1     

結果を新しい列として追加したいのですが、次のように既存の$1に追加したいと思います。

$ cut -f1 file_sort.csv
3 2022-12-01
3 2022-12-01
2 2022-12-01
2 2022-12-01

uniq行の値を新しい列として保存する方法はありますか?このように:

$ cut -f1 file_sort.csv
3
3
2
2

ベストアンサー1

あなたが望むのは、最初のフィールドから最後のフィールドに数字を移動することだけです。これを指定しませんが、cut表示されたコマンドを使用すると、ファイルがタブで区切られていることを意味します。そのuniq -c場合は、出力が空白(表示されていない)で行を埋め、発生後にタブを追加しないことを考えると、次のように簡単に操作できます。

$ sort file.csv | uniq -c | sort -nr | perl -pe 's/^\s+(\d+) (.*)/$2\t$1/' 
2022-12-01  YELLOW  2   3
2022-12-01  RED 2   3
2022-12-01  YELLOW  1   2
2022-12-01  RED 1   2

または以下sedをサポートします-E

$ sort file.csv | uniq -c | sort -nr | sed -E 's/^ *([0-9]*) (.*)/\2\t\1/' 
2022-12-01  YELLOW  2   3
2022-12-01  RED 2   3
2022-12-01  YELLOW  1   2
2022-12-01  RED 1   2

そしてどんなsedでも:

$ sort file.csv | uniq -c | sort -nr | sed 's/^ *\([0-9]*\) \(.*\)/\2\t\1/' 
2022-12-01  YELLOW  2   3
2022-12-01  RED 2   3
2022-12-01  YELLOW  1   2
2022-12-01  RED 1   2

または、数を計算してawk目的の場所にフィールドを追加してから、4番目のフィールドに基づいてソートすることもできます。

$ awk -F'\t' -v OFS='\t' '{ cnt[$0]++ } 
                          END{
                            for(line in cnt){
                              print line,cnt[line]
                            }
                          }' file.csv | sort -nrk4,4 
2022-12-01  YELLOW  2   3
2022-12-01  RED 2   3
2022-12-01  YELLOW  1   2
2022-12-01  RED 1   2

おすすめ記事