Polecenie uniksowe, aby sprawdzić, czy jakieś dwa wiersze w pliku są takie same?

24

Czy istnieje polecenie uniksowe, które może sprawdzić, czy jakieś dwa wiersze w pliku są takie same?

Na przykład rozważ plik sentences.txt

This is sentence X
This is sentence Y
This is sentence Z
This is sentence X
This is sentence A
This is sentence B

Widzimy to zdanie

This is sentence X

jest powtorzone.

Czy jest jakieś polecenie, które może to szybko wykryć, aby być może mógłbym wykonać to w ten sposób -

$ cat sentences.txt | thecommand
Line 1:This is sentence X
Line 4:This is sentence X
CodeBlue
źródło

Odpowiedzi:

40

Oto jeden ze sposobów uzyskania dokładnie tego, czego szukasz:

$ grep -nFx "$(sort sentences.txt | uniq -d)" sentences.txt 
1:This is sentence X
4:This is sentence X

Wyjaśnienie:

Wewnętrzny $(sort sentences.txt | uniq -d)wyświetla każdą linię, która występuje więcej niż jeden raz. Zewnętrzne grep -nFxponownie szuka sentences.txtdokładnych -xdopasowań do dowolnej z tych linii -Fi poprzedza ich numer linii-n

grebneke
źródło
Twoja edycja ledwo mnie pobiła od opublikowania tej samej odpowiedzi. +1
skrzynka
Więc składnia $ (polecenie) działa jako rodzaj zamiany?
CodeBlue
2
@CodeBlue - tak. Nazywa się to Command Substitution
grebneke
8
sort sentences.txt | uniq -d | grep -nFxf - sentences.txtbyłby nieco bardziej wydajny i pozwoliłby uniknąć potencjalnych arg list too longproblemów.
Stéphane Chazelas
10

Nie dokładnie to, czego chcesz, ale możesz spróbować połączyć sorti uniq -c -d:

aularon@aularon-laptop:~$ cat input
This is sentence X
This is sentence Y
This is sentence Z
This is sentence X
This is sentence A
This is sentence B

aularon@aularon-laptop:~$ sort input | uniq -cd
      2 This is sentence X
aularon@aularon-laptop:~$ 

2oto liczba znalezionych duplikatów dla linii, z man uniq:

   -c, --count
          prefix lines by the number of occurrences

   -d, --repeated
          only print duplicate lines
aularon
źródło
6

JEŚLI zawartość pliku mieści się w pamięci awkjest do tego dobra. Standardowy jeden wiersz w pliku comp.lang.awk (nie mogę przeszukiwać instancji z tego komputera, ale co miesiąc jest kilka), aby wykryć, że występuje duplikacja, awk 'n[$0]++'zlicza wystąpienie każdej wartości wiersza i drukuje każde wystąpienie inny niż pierwszy, ponieważ domyślną akcją jest print $0.

Aby wyświetlić wszystkie wystąpienia, w tym pierwsze, w twoim formacie, ale być może w mieszanej kolejności, gdy zduplikowana jest więcej niż jedna wartość, staje się nieco bardziej wybredna:

awk <sentences.txt ' !($0 in n) {n[$0]=NR;next} \
    n[$0] {n[$0]=0; print "Line "n[$0]":"$0} \
    {print "Line "NR":"$0} '

Pokazane w wielu wierszach dla przejrzystości, zwykle biegasz razem w prawdziwym użyciu. Jeśli robisz to często, możesz umieścić awkskrypt w pliku za pomocą awk -f, lub oczywiście całą rzecz w skrypcie powłoki. Jak najprostsze, awkmożna to zrobić bardzo podobnie perl -n[a].

dave_thompson_085
źródło