Bir dosyadaki yinelenen satırları bulun ve her satırın kaç kez kopyalandığını sayın?


529

Aşağıdakine benzer bir dosyam olduğunu varsayalım:

123 
123 
234 
234 
123 
345

Kaç kez '123' kopyalandığını, kaç kez '234' kopyalandığını vs. bulmak istiyorum. İdeal olarak çıktı şöyle olur:

123  3 
234  2 
345  1

4
Hangi dili kullanmak istiyorsun?
VMAtm

Yanıtlar:


791

Satır başına bir sayı olduğunu varsayarsak:

sort <file> | uniq -c

--countGNU sürümü ile daha ayrıntılı bayrağı da kullanabilirsiniz , örneğin Linux'ta:

sort <file> | uniq --count

3
Ancak algoritmik olarak yaptığım şey bu en verimli yaklaşım (O (n log n) * avg_line_len burada n satır sayısı) gibi görünmüyor. Birkaç gigabayt büyük dosyalar üzerinde çalışıyorum, bu yüzden performans önemli bir konudur. Bir önek ağacı (benim durumumda dizeleri genellikle ortak önekleri vardır) veya benzeri kullanarak tek bir geçişte sayma yapan bir araç olup olmadığını merak ediyorum, o (n) * avg_line_len hile yapmak gerekir. Böyle bir komut satırı aracını bilen var mı?
Droggl

21
Ek bir adım, bunun çıktısını son bir 'sort -n' komutuna bağlamaktır. Bu, çizgilerin en sık meydana geldiği sonuçları sıralayacaktır.
samoz

79
Yalnızca yinelenen satırlar yazdırmak istiyorsanız, 'uniq -d' kullanın
DmitrySandalov

6
Sonucu tekrar sıralamak isterseniz, tekrar kullanabilirsiniz sort:sort <file> | uniq -c | sort -n
Abhishek Kashyap

413

Bu, yalnızca yinelenen satırları sayılarak yazdırır :

sort FILE | uniq -cd

veya GNU uzun seçenekleriyle (Linux'ta):

sort FILE | uniq --count --repeated

üzerinde BSD ve OSX sen grep kullanmak zorunda eşsiz hatları üzerinden filtreye:

sort FILE | uniq -c | grep -v '^ *1 '

Verilen örnek için sonuç şöyle olacaktır:

  3 123
  2 234

Yalnızca bir kez görünen satırlar dahil tüm satırların sayılarını yazdırmak istiyorsanız :

sort FILE | uniq -c

veya GNU uzun seçenekleriyle (Linux'ta):

sort FILE | uniq --count

Verilen giriş için çıktı:

  3 123
  2 234
  1 345

Amacıyla çıktıyı sıralamak üstünde en sık çizgilerle, (tüm sonuçları almak için) şunları yapabilirsiniz:

sort FILE | uniq -c | sort -nr

veya yalnızca yinelenen satırları elde etmek için, en sık kullanılanı:

sort FILE | uniq -cd | sort -nr

OSX ve BSD'de sonuncusu:

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr

1
- Tekrarlanan veya -d seçeneği ile iyi bir nokta. "| Grep 2" ya da benzerini kullanmaktan çok daha doğru!
Lauri

Tekrarlama sayısı 100'den fazla olan tüm satırları almak için bu komutu nasıl değiştirebilirim?
Black_Rider

@Black_Rider Boruya | sort -nveya ekleme | sort -nr, çıkışı tekrar sayısına göre sıralar (sırasıyla artan veya azalan). İstediğiniz bu değil ama yardımcı olabileceğini düşündüm.
Andrea

1
@Black_Rider awk her türlü hesaplamayı yapabilir gibi görünüyor: senin durumunda yapabilirsin| awk '$1>100'
Andrea

4
@fionbio Görünüşe göre OSX uniq'te -c ve -d'yi birlikte kullanamazsınız . İşaret ettiğiniz için teşekkürler. Şunları yapabilirsiniz benzersiz satırları filtrelemek için grep kullanın :sort FILE | uniq -c | grep -v '^ *1 '
Andrea

72

Birden çok dosyada yinelenen satırları bulmak ve saymak için aşağıdaki komutu deneyebilirsiniz:

sort <files> | uniq -c | sort -nr

veya:

cat <files> | sort | uniq -c | sort -nr

30

Üzerinden :

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data

Olarak awk 'dups[$1]++'komut, değişken $1column1 tüm içeriği tutan ve köşeli parantezler dizi erişimi bulunmaktadır. Bu nedenle, datadosyadaki her 1. satır sütunu için , adlandırılan dizinin düğümü dupsartırılır.

Ve sonunda, değişken olarak dupsdizi üzerinde döngü yapıyoruz numve önce kaydedilen sayıları sonra kopya değerlerini yazdırıyoruz dups[num].

Giriş dosyanızın bazı satırların sonunda boşluk olduğunu unutmayın, bunları temizlerseniz yukarıdaki komut $0yerine kullanabilirsiniz $1:)


1
Sahip olduğumuzu düşünürsek bu biraz abartılı değil uniqmi?
Nathan Fellman

9
sort | uniqve awk çözümü oldukça farklı performans ve kaynak değiş tokuşlarına sahiptir: dosyalar büyükse ve farklı satır sayısı azsa, awk çözümü çok daha verimlidir. Satır sayısında doğrusaldır ve alan kullanımı farklı satır sayısında doğrusaldır. Awch çözümünün tüm farklı satırları bellekte tutması gerekirken (GNU) sıralaması geçici dosyalara başvurabilir.
Lars Noschinski

14

"Windows PowerShell" kullanan pencerelerde bunu başarmak için aşağıda belirtilen komutu kullandım

Get-Content .\file.txt | Group-Object | Select Name, Count

Ayrıca sonucu filtrelemek için where-nesne Cmdlet'ini kullanabiliriz

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count

dosyanın sıralama düzenini değiştirmeden sonuncusu hariç tüm yinelemeleri silebilir misiniz?
jparram

6

Standart bir Unix kabuğuna ve / veya cygwin ortamına erişiminiz olduğunu varsayarsak:

tr -s ' ' '\n' < yourfile | sort | uniq -d -c
       ^--space char

Temel olarak: tüm boşluk karakterlerini satır satırlarına dönüştürün, sonra aktarılan çıktıyı sıralayın ve bunu uniq'e besleyin ve yinelenen satırları sayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.