Usando uniq -f 1 fornece resultados inesperados

1

Depois de fazer uma pergunta no ubuntuforums.org e não conseguir uma resposta satisfatória, eu decidi fazer a pergunta novamente aqui no Ask Ubuntu. Eu preciso da resposta para ser muito detalhada. Especificamente, eu preciso saber quais linhas são comparadas todas as vezes uma linha é impressa usando uniq para os dois exemplos seguintes:

arquivo1.txt:

$ cat -A file1.txt
aaa^Iupc$
b$
c$
aaa^Iztp$
b$
c$
C$
A$
B$
B$
b$

$ sort file1.txt | uniq -f 1
A
aaa    upc
aaa    ztp
b

e arquivo2.txt:

$ cat -A file2.txt
aaa^Iupc$
b$
c$
aaa^Iztp$
b$
c$
C$
A$
B$
B$
bbb^Ixpz$

$ sort file2.txt | uniq -f 1
A
aaa    upc
aaa    ztp
b
bbb    xpz
c

Estou confuso sobre o segundo exemplo. Eu não entendo como é que o B maiúsculo não acaba na saída final. A linha com letra maiúscula B não deveria ser impressa, dado que as linhas B e bbb xpz são adjacentes umas às outras? Se:

B ---> (empty)

e

bbb ---> xpz

um valor vazio e xpz são únicos, portanto, ambas as linhas devem ser impressas. Ou estou faltando alguma coisa?

    
por John_Patrick_Mason 09.06.2017 / 03:01

2 respostas

2

A resposta está na ordem de classificação e o que o uniq usa para um valor de campo quando há menos que o número de campo especificado ( N ) ao usar -f N .

Como vimos, você tem conjuntos de caracteres ASCII, portanto, a ordem de classificação é muito previsível:

% sort file.txt            
A
aaa upc
aaa ztp
b
b
B
B
bbb xpz
c
c
C

Agora, vamos usar uniq -f 1 para obter linhas exclusivas com o primeiro campo (separado por espaços em branco) de cada linha durante a verificação:

% sort file.txt | uniq -f 1
A
aaa upc
aaa ztp
b
bbb xpz
c

Agora, é importante notar que uniq usa string nula para linhas que tem menos que os campos mencionados, 1 neste caso; Assim, todas as linhas que têm apenas um campo seriam tratadas como tendo sequências nulas para outros campos, comparando com outras linhas com campos > = 2.

Então, da sort file2.txt output:

b
b
B
B

seriam todos tratados como iguais e somente a primeira linha contendo b seria preservada, por isso você tem um b na saída.

Da mesma forma, de:

c
c
C

apenas o primeiro c acabaria na saída de uniq .

    
por heemayl 09.06.2017 / 03:13
0

Veja uma tabela que pode ajudá-lo a trabalhar no processo:

----------------+---------------+----------+----------------+
    sort        |     Remove    | Adjacent |                |
 (C locale)     |    field #1   |  match?  |    Output      |
----------------+---------------+----------+----------------+
A               |               |    N*    |A               |
B               |               |    Y     |                |
B               |               |    Y     |                |
C               |               |    Y     |                |
aaa     upc     |   upc         |    N     |aaa     upc     |
aaa     ztp     |   ztp         |    N     |aaa     ztp     |
b               |               |    N     |b               |
b               |               |    Y     |                |
bbb     xpz     |   xpz         |    N     |bbb     xpz     |
c               |               |    N     |c               |
c               |               |    Y     |                |
----------------+---------------+----------+----------------+
* the first line has no adjacent above, so is always output
    
por steeldriver 09.06.2017 / 04:56