Benzersiz çizgiler yazdırma


15

Bir kombinasyonu dışındaki benzersiz satırları yazdırmak için daha iyi bir çözüm var mı sortve uniq?


1
"Daha iyi" ile ne demek istiyorsun?
gabe.

@gabe Örneğin, tüm dosyanın belleğe kaydedilmesini gerektirmez.
13'te Let_Me_Be

sortGiriş RAM'e sığmayacak kadar büyükse, bazı sürümleri (örn. GNU coreutils) geçici dosyalar ve harici birleştirme kullanır. Ve diğer birçok versiyonda bir -mseçenek vardır, bu da girişi (örn. split
İle

Yanıtlar:


25

Aynı satırların her birini yalnızca bir sırayla yazdırmak için:

sort -u

Yalnızca benzersiz çizgileri herhangi bir sırayla yazdırmak için:

sort | uniq -u

Her bir özdeş çizgiyi ilk ortaya çıkma sırasına göre yalnızca bir kez yazdırmak için: (her satır için henüz görülmediyse satırı yazdırın, her durumda görülen sayacı artırın)

awk '!seen[$0] {print}
     {++seen[$0]}'

Yalnızca benzersiz satırları ilk gerçekleşme sıralarına göre yazdırmak için: (her satırı girişe seenve ayrıca linesilk gerçekleşme durumuna da kaydedin; girişin sonunda satırları oluşma sırasına göre yazdırın, yalnızca yalnızca görünen satırları yazdırın bir Zamanlar)

awk '!seen[$0]++ {lines[i++]=$0}
     END {for (i in lines) if (seen[lines[i]]==1) print lines[i]}'

8
nasıl awk '!seen[$0]++ {print}'?
asoundmove

10
Ya da daha kısa awk '!seen[$0]++', çünkü {print}boş bir komutla ima edilir.
quazgar

3

Bazı (en çok?) Sürümlerinde parçayı doğrudan yapan sortbir -ubayrak bulunur uniq. Ancak uygulamaya bağlı olarak bazı satır uzunluğu kısıtlamaları olabilir, ancak zaten düz olanlara sahiptiniz sort|uniq.


1
Er? sort -uen azından V7'ye geri dönüyor.
geekosaur

Hum ... Solaris veya AIX'in buna sahip olmadığını hatırladığımı sanıyordum. Yine de yanılıyorum, ikisinde de var.
Mat

Solaris ve AIX, -uaynı zamanda 512 karakterlik bir satır uzunluğu sınırlamasına sahiptir. (Aslında, Solaris 9 Sun'un etrafında bir yerde onu 5120'ye çıkardığını düşünüyorum. GNU yine de kazanıyor.)
geekosaur

@geekosaur: Emin misin? Hat uzunluğundaki 512 baytlık sınırı ayırmak için yapılan çalışmalar JP Linderman, Bell System Technical tarafından 'Çalışan bir Sıralama Rutininin Yapımında Teori ve Uygulama' bölümünde belgelenmiştir. Journal, 63, 1827-1843 (1984).
Jonathan Leffler

0

Perl sizin için çalışıyor mu? Kopyalar bitişik olmasa bile çizgileri orijinal sırada tutabilir. Ayrıca Python veya 'da kodlayabilirsiniz awk.

while (<>) {
    print if $lines{$_}++ == 0;
}

Hangi sadece kısaltılabilir

perl -ne 'print unless $lines{$_}++;'

Verilen girdi dosyası:

abc
def
abc
ghi
abc
def
abc
ghi
jkl

Çıktı verir:

abc
def
ghi
jkl

$ Lines nerede tanımlanıyor?
Gregg Leventhal

Öyle değil. Bir use strict;veya olmadığından use warnings;(aslında, strictburada en alakalı olanı), %linestanımlanmadan önce kullanma konusunda herhangi bir şikayet yoktur . Dar çizgilerle çalıştırılırsa my %lines;, döngüden önce bir çizgi olması gerekir . Şunu da belirtmek gerekir ki, karma %lines; karma $lines{$_}değerine bir gösterim yoluyla başvurulur .
Jonathan Leffler

sortÇözümlerin büyük miktarda veri için daha iyi olabileceğini düşünüyorum (OP "tüm dosyayı hafızada saklamaktan endişe duyuyordu"). sortveriler kullanılabilir bellekten daha büyükse çekirdek dışı sıralama yapar.
Kusalananda

0

Şu sorunun cevabının son kısmında: Bu soruya cevap olarak @Gilles tarafından benzersiz satırlar basmak için iki karma kullanma ihtiyacını ortadan kaldırmaya çalıştım.

Bu çözüm şöyledir: Yalnızca benzersiz satırları ilk oluşma sırasına göre yazdırmak için:

awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'

Burada, "sayaç" her satırın daha önce işlenene benzer bir sayısını saklar.
Sonunda, yalnızca sayaç değeri 1 olan satırları yazdırırız.

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.