Saya memiliki file .csv seperti ini:
stack2@example.com,2009-11-27 01:05:47.893000000,example.net,127.0.0.1
overflow@example.com,2009-11-27 00:58:29.793000000,example.net,255.255.255.0
overflow@example.com,2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...
Saya harus menghapus duplikat email (seluruh baris) dari file (yaitu salah satu baris yang berisi [email protected]
contoh di atas). Bagaimana cara menggunakan uniq
hanya bidang 1 (dipisahkan dengan koma)? Menurut man
, uniq
tidak memiliki opsi untuk kolom.
Saya mencoba sesuatu sort | uniq
tetapi tidak berhasil.
man sort
). Itu singkatan dari posisi awal dan berhenti.sort
dikatakan halaman manual: "-u
,--unique
dengan-c
, periksa untuk pemesanan yang ketat; tanpa-c
, hasilkan hanya yang pertama dari proses yang sama ." Jadi, ini memang "kejadian duplikat pertama sebelum memilah."-F
mengatur pemisah bidang.$1
adalah bidang pertama._[val]
mencarival
di hash_
(variabel biasa).++
kenaikan, dan mengembalikan nilai lama.!
mengembalikan logika tidak.sumber
awk -F',' '{ x[$1]=$0 } END { for (i in x) print x[i] }' file
!_[$1][$2]++
dapat digunakan untuk mengurutkan berdasarkan dua bidang pertama.awk
-Fu saya tidak cukup kuat untuk dapat unik di berbagai bidang, meskipun. :(Untuk mempertimbangkan beberapa kolom.
Sortir dan berikan daftar unik berdasarkan kolom 1 dan kolom 3:
-t :
usus besar adalah pemisah-k 1,1 -k 3,3
berdasarkan kolom 1 dan kolom 3sumber
atau jika Anda ingin menggunakan uniq:
<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
memberi:
sumber
cat
! Daripada mem-pip ke tr, biarkan tr membaca file menggunakan<
. Menyalurkan melalui pipacat
adalah komplikasi umum yang tidak perlu yang digunakan oleh pemula. Untuk sejumlah besar data ada efek kinerja yang bisa didapat.rev
.Jika Anda ingin mempertahankan duplikat terakhir yang bisa Anda gunakan
Yang merupakan persyaratan saya
sini
tac
akan membalikkan file baris demi barissumber
Ini cara yang sangat bagus.
Pertama memformat konten sedemikian rupa sehingga kolom yang akan dibandingkan untuk keunikan adalah lebar tetap. Salah satu cara untuk melakukan ini adalah menggunakan printf awk dengan specifier lebar bidang / kolom ("% 15s").
Sekarang opsi -f dan -w dari uniq dapat digunakan untuk melewati bidang / kolom sebelumnya dan untuk menentukan lebar perbandingan (kolom) lebar.
Inilah tiga contoh.
Dalam contoh pertama ...
1) Untuk sementara, buat kolom yang menarik menjadi lebar tetap lebih besar atau sama dengan lebar maks bidang.
2) Gunakan opsi -f uniq untuk melewati kolom sebelumnya, dan gunakan opsi -w uniq untuk membatasi lebar ke tmp_fixed_width.
3) Hapus spasi tambahan dari kolom untuk "mengembalikan" lebarnya (dengan asumsi tidak ada spasi tambahan sebelumnya).
Dalam contoh kedua ...
Membuat kolom uniq baru 1. Kemudian hapus setelah filter uniq diterapkan.
Contoh ketiga sama dengan yang kedua, tetapi untuk banyak kolom.
sumber
baik, lebih sederhana daripada mengisolasi kolom dengan awk, jika Anda perlu menghapus semuanya dengan nilai tertentu untuk file yang diberikan, mengapa tidak hanya melakukan grep -v:
misalnya untuk menghapus semuanya dengan nilai "col2" di baris tempat kedua: col1, col2, col3, col4
Jika ini tidak cukup baik, karena beberapa baris mungkin dihilangkan secara tidak benar dengan kemungkinan nilai yang cocok ditampilkan di kolom yang berbeda, Anda dapat melakukan sesuatu seperti ini:
awk untuk mengisolasi kolom yang menyinggung: mis
-F menetapkan bidang yang dibatasi untuk ",", $ 2 berarti kolom 2, diikuti oleh beberapa pembatas khusus dan kemudian seluruh baris. Anda kemudian dapat memfilter dengan menghapus garis yang dimulai dengan nilai yang menyinggung:
dan kemudian menghapus barang-barang di depan pembatas:
(note - perintah sed ceroboh karena tidak termasuk nilai pelolosan. Juga pola sed harus benar-benar seperti "[^ |] +" (yaitu apa pun yang bukan pembatas). Tapi semoga ini cukup jelas.
sumber
Dengan menyortir file dengan
sort
terlebih dahulu, Anda kemudian dapat mendaftaruniq
.Tampaknya mengurutkan file dengan baik:
Anda juga bisa melakukan beberapa sihir AWK:
sumber
sort
, makauniq
,sort
perlu dilakukan sebelum melakukanuniq
sebaliknya jika tidak bekerja (tetapi Anda dapat melewati perintah kedua dan hanya menggunakansort -u
). Dariuniq(1)
: "Saring baris pencocokan yang berdekatan dari INPUT (atau input standar), tulis ke OUTPUT (atau output standar)."