私のフォルダには、次のようなさまざまなcsvファイル(megadrive.txt、snes.txt)があります。
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;;;;;;;;0;;;;;
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;1990;Sega;Shooter;;;;;0;;;;;
After Burner (World);After Burner (World);Sega Master System;;;;;;;;;;;;;;
After Burner (World);After Burner (World);Sega Master System;;1988;Sega;Flying;;;;;0;;;;;
Air Rescue (Europe);Air Rescue (Europe);Sega Master System;;1992;Sega;Shooter;;;;;0;;;;;
Aladdin (Europe);Aladdin (Europe);Sega Master System;;1994;Sega;Platform;;;;;0;;;;;
このCSVには多数の行があり、多くの行に同じ最初のフィールドがあります。これらのファイルをバッチ処理し、各ファイル内の各最初のフィールドの最長行だけを維持したいと思います。たとえば、出力は次のようになります。
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;1990;Sega;Shooter;;;;;0;;;;;
After Burner (World);After Burner (World);Sega Master System;;1988;Sega;Flying;;;;;0;;;;;
Air Rescue (Europe);Air Rescue (Europe);Sega Master System;;1992;Sega;Shooter;;;;;0;;;;;
Aladdin (Europe);Aladdin (Europe);Sega Master System;;1994;Sega;Platform;;;;;0;;;;;
特に
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;;;;;;;;0;;;;;
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;1990;Sega;Shooter;;;;;0;;;;;
どちらのレコードにも重複した最初のフィールドがありますが、2番目の項目が長いため、2番目の項目を最後に保持し、同じ最初のフィールドを持つ短い行をすべて削除したいと思います。
どうすればいいですか?
ベストアンサー1
あなたのフィールドがによって定義されているとします;
。そして;
現場にはコンテンツがありません。これらの仮定が成立している場合は、次のことができます。
$ awk -F';' '{if(!a[$1]||length($0)>length(a[$1])){a[$1]=$0}}END{for(i in a){print a[i]}}' file.txt
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;1990;Sega;Shooter;;;;;0;;;;;
After Burner (World);After Burner (World);Sega Master System;;1988;Sega;Flying;;;;;0;;;;;
Aladdin (Europe);Aladdin (Europe);Sega Master System;;1994;Sega;Platform;;;;;0;;;;;
Air Rescue (Europe);Air Rescue (Europe);Sega Master System;;1992;Sega;Shooter;;;;;0;;;;;
しかし、これはメモリの最初のフィールドごとに1行を保存する必要があるという欠点があり、これは大容量ファイルの場合に問題になる可能性があります。その場合は、次のことを試すことができます。
$ awk '{print length($0)";"$0}' file.txt | sort -t';' -rnk1,1 | awk -F';' '++a[$2]==1' | cut -d';' -f2-
Aerial Assault (USA);Aerial Assault (USA);Sega Master System;;;;;;;;;0;;;;;
After Burner (World);After Burner (World);Sega Master System;;;;;;;;;;;;;;
Air Rescue (Europe);Air Rescue (Europe);Sega Master System;;1992;Sega;Shooter;;;;;0;;;;;
Aladdin (Europe);Aladdin (Europe);Sega Master System;;1994;Sega;Platform;;;;;0;;;;;
単純なシェルループを使用して、両方のソリューションのいずれかをすべてのファイルに適用できます。
for f in *txt; do
awk -F';' '{if(!a[$1]||length($0)>length(a[$1])){a[$1]=$0}}END{for(i in a){print a[i]}}' "$f" > "$f".fixed
done
または
for f in *txt; do
awk '{print length($0)";"$0}' file.txt | sort -t';' -rnk1,1 |
awk -F';' '++a[$2]==1' | cut -d';' -f2- > "$f".fixed
done