Verileri sıralamak zorunda kalmadan sadece benzersiz sonuçlar nasıl elde edilir?


40
$ cat data.txt 
aaaaaa
aaaaaa
cccccc
aaaaaa
aaaaaa
bbbbbb
$ cat data.txt | uniq
aaaaaa
cccccc
aaaaaa
bbbbbb
$ cat data.txt | sort | uniq
aaaaaa
bbbbbb
cccccc
$

İhtiyacım olan sonuç, dosyadaki orijinal ifadelerin sırasını korurken tüm kopyaları (sadece ardışık olanları değil) kaldırarak orijinal dosyadaki tüm satırları görüntülemek .

İşte, bu örnekte, aslında aradığım sonuç şuydu:

aaaaaa
cccccc
bbbbbb

uniqGenel olarak bu genel işlemi nasıl gerçekleştirebilirim ?

Yanıtlar:


54
perl -ne 'print unless $seen{$_}++' data.txt

Veya işe yaramaz bir kullanımınızcat varsa :

cat data.txt | perl -ne 'print unless $seen{$_}++'

İşte awkPerl eksikliği olan sistemler için bir çeviri:

awk '!seen[$0]++' data.txt
cat data.txt | awk '!seen[$0]++'

3
Biraz daha kısa awk komut dosyası{ if (!seen[$0]++) print }
camh

1
@ fred, dosyanız gerçekten büyük değilse, sürümlerin çalışması, çalıştırdığından daha uzun sürer.
cjm

8
Awk sürümü dışarı bırakarak daha kısa yapılabilir if, print:, parantez ve parantezawk '!seen[$0]++'
Gordon Davisson

2
@Legate, gördüğümüz her satırı kaydettiğimiz dizinin adı . Her türlü '!LarryWall[$0]++'umursamayan şey için onu değiştirebilirsin , ama "görüldü" insanların programı daha iyi anlamalarına yardımcı olur.
cjm,

1
@Sadi, bu gerçekten bir soru olarak sorulmuş olmalı, yorum değil. Ancak bu dosyadaki satırların bazıları bir boşlukta bitiyor, bazıları ise bitmiyor. Bu komutlar, sonundaki boşluklar da dahil olmak üzere tüm çizgiyi önemli görür.
cjm

13

john adlı bir araç var unique:

usr@srv % cat data.txt | unique out
usr@srv % cat out
aaaaaa
cccccc
bbbbbb

Aynısını tek bir komut satırında ek araçlar olmadan elde etmek biraz daha karmaşıktır:

usr@srv % cat data.txt | nl | sort -k 2 | uniq -f 1 | sort -n | sed 's/\s*[0-9]\+\s\+//'
aaaaaa
cccccc
bbbbbb

nlSatır numaralarını satırların önüne basar, böylece biz sort/ uniqarkamızda satırların orijinal sırasını geri yükleyebiliriz. sedsonra satır numaralarını siler;)


Aynı şeyi yapabilen ortak linux komutlarının herhangi bir kombinasyonu var mı?
Lazer

7
"Verileri sıralamak zorunda kalmadan" neyi özledin?
Totor

@Totor - bkz menkus ' yanıtını benzer bir yorumuna. @binfalse - ikinci çözümünüz işe yaramıyor (belki bu önemsiz örnekle çalışıyor, ancak bazı gerçek hayat girişleriyle çalışmıyor). Lütfen bunu düzeltin, örneğin bu daima işe nl -ba -nrz data.txt | sort -k2 -u | sort | cut -f2
yaramalıdır

6

Bunu kullanmayı tercih ederim:

cat -n data.txt | sort --key=2.1 -b -u | sort -n | cut -c8-

cat -n Satır numaraları ekler.

sort --key=2.1 -b -u ikinci alanı sıralar (eklenen satır numaralarından sonra), satır boşluklarını yok sayar, benzersiz satırları korur

sort -n katı sayısal sıralamaya göre sıralar

cut -c8- tüm karakterleri sütun 8'den EOL'ye getir (örneğin, eklediğimiz satır numaralarını atla)


5
> Verileri sıralamak zorunda kalmadan sadece benzersiz sonuçlar nasıl elde edilir? > veri sıralamak zorunda kalmadan
Jan Wikholm

7
'verileri sıralamak zorunda kalmadan' sadece başlıkta görünür. Asıl ihtiyaç: "dosyadaki orijinal ifadelerin sırasını korurken tüm kopyaları (sadece ardışık olanları değil) kaldırarak orijinal dosyadaki tüm satırları görüntülemek."
menkus

1
@menkus anahtar "dosyadaki ifadelerin orijinal sırasını korurken" dir. Bu cevap bunu başaramadı.
Andrew Ferrier

2

Perl'de kullanabileceğiniz, adı verilen bir işlevi içeren bir modül vardır uniq. Bu nedenle, Perl'de bir diziye yüklenen verilerinizi açtıysanız, benzersiz olması için fonksiyonunu çağırmanız yeterlidir, ancak yine de orijinal sırayı koruyabilirsiniz.

use List::MoreUtils qw(uniq)    
@output = uniq(@output);

Bu modül hakkında daha fazla bilgiyi burada bulabilirsiniz: List :: MoreUtils


Bu, 500 GB gibi büyük dosyaları yönetebilir mi?
Çocuk
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.