Encontre linhas exclusivas

92

Como posso encontrar as linhas exclusivas e remover todas as duplicatas de um arquivo? Meu arquivo de entrada é

1
1
2
3
5
5
7
7

Eu gostaria que o resultado fosse:

2
3

sort file | uniqnão vai fazer o trabalho. Irá mostrar todos os valores 1 vez

amprantino
fonte
17
O arquivo deve ser classificado primeiro. sort file | uniq -uirá imprimir no console para você.
ma77c de
Acho que o motivo de sort file | uniqmostrar todos os valores 1 vez é porque ele imprime imediatamente a linha que encontra na primeira vez e, para os encontros subsequentes, simplesmente os ignora.
Reeshabh Ranjan

Respostas:

91

uniq tem a opção de que você precisa:

   -u, --unique
          only print unique lines
$ cat file.txt
1
1
2
3
5
5
7
7
$ uniq -u file.txt
2
3
Lev Levitsky
fonte
33
Certifique-se de classificar se as entradas no arquivo já foram ou não classificadas. sort file.txt | uniq
user3885927
veja minha resposta se não quiser classificar primeiro. stackoverflow.com/a/54803217/5441945
hychou
28

Use da seguinte maneira:

sort < filea | uniq > fileb
Kasavbere
fonte
2
Isso não está correto, acho que você quis dizer:uniq -u filea > fileb
Chris Seymour
1
Eu copiar seus dados e executá-lo e ele funciona: sort<filea.txt | uniq>fileb.txt. Talvez você tenha omitido as extensões. Estou usando um Mac OS X. você tem que ir filea.txtpara outrofileb.txt
Kasavbere
Não há necessidade de redirecionamento com sorte para que serve uniqquando você pode apenas fazer sort -u file -o fileo que está fazendo é remover os valores duplicados ou seja, filebcontém 1,2,3,5,7o OP deseja as linhas únicas que são 2,3e são alcançadas pela uniq -u fileextensão do arquivo não tem nada com isso, sua resposta está errada.
Chris Seymour
13

Você também pode imprimir o valor único em "arquivo" usando o catcomando direcionando para sorteuniq

cat file | sort | uniq -u

código do céu
fonte
9

uniq -u tem me deixado louco porque não funcionou.

Então, em vez disso, se você tiver python (a maioria das distros e servidores Linux já o tem):

Supondo que você tenha o arquivo de dados em notUnique.txt

#Python
#Assuming file has data on different lines
#Otherwise fix split() accordingly.

uniqueData = []
fileData = open('notUnique.txt').read().split('\n')

for i in fileData:
  if i.strip()!='':
    uniqueData.append(i)

print uniqueData

###Another option (less keystrokes):
set(open('notUnique.txt').read().split('\n'))

Observe que, devido às linhas vazias, o conjunto final pode conter '' ou apenas strings de espaço. Você pode remover isso mais tarde. Ou simplesmente copie do terminal;)

#

Apenas para sua informação, da página de manual da uniq:

"Nota: 'uniq' não detecta linhas repetidas a menos que sejam adjacentes. Você pode querer classificar a entrada primeiro ou usar 'sort -u' sem 'uniq'. Além disso, as comparações respeitam as regras especificadas por 'LC_COLLATE'."

Uma das maneiras corretas de invocar com: # sort nonUnique.txt | uniq

Exemplo de execução:

$ cat x
3
1
2
2
2
3
1
3

$ uniq x
3
1
2
3
1
3

$ uniq -u x
3
1
3
1
3

$ sort x | uniq
1
2
3

Os espaços podem ser impressos, então esteja preparado!

ashmew2
fonte
3
Isso é um exagero.
SmallChess de
9

Embora sortleve um tempo O (n log (n)), eu prefiro usar

awk '!seen[$0]++'

awk '!seen[$0]++'é uma abreviatura de awk '!seen[$0]++ {print}'print line (= $ 0) se seen[$0]não for zero. É preciso mais espaço, mas apenas tempo O (n).

Hychou
fonte
7

você pode usar:

sort data.txt| uniq -u

este classifica os dados e filtra por valores únicos

mais Preto
fonte
4

uniq -u < file fará o trabalho.

Shiplu Mokaddim
fonte
Não há necessidade de redirecionamento.
Chris Seymour
Sim eu sei. Fez isso habitualmente
Shiplu Mokaddim
3

uniq deve funcionar bem se o seu arquivo for / puder ser classificado, se você não puder classificar o arquivo por algum motivo, você pode usar awk :

awk '{a[$0]++}END{for(i in a)if(a[i]<2)print i}'


fonte
3
sort -d "file name" | uniq -u

isso funcionou para mim por um semelhante. Use isto se não estiver combinado. Você pode remover a classificação, se for organizado

a_rookie_seeking_answers
fonte
3

Acho isso mais fácil.

sort -u input_filename > output_filename

-u significa único.

Anant Mittal
fonte
0

Foi a primeira vez que tentei

skilla:~# uniq -u all.sorted  

76679787
76679787 
76794979
76794979 
76869286
76869286 
......

Depois de fazer um gato-e tudo.

skilla:~# cat -e all.sorted 
$
76679787$
76679787 $
76701427$
76701427$
76794979$
76794979 $
76869286$
76869286 $

Cada segunda linha tem um espaço à direita :( Depois de remover todos os espaços à direita, funcionou!

obrigado

amprantino
fonte