Использование uniq -f 1 дает неожиданные результаты

Использование uniq -f 1 дает неожиданные результаты

Задав вопрос на ubuntuforums.org и не получив удовлетворительного ответа, я решил задать вопрос снова здесь, на Ask Ubuntu. Мне нужен очень подробный ответ. В частности, мне нужно знатькоторыйлинии сравниваютсякаждый разВ следующих двух примерах строка выводится с использованием uniq:

файл1.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

и файл2.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

Я запутался во втором примере. Я не понимаю, почему заглавная буква B не попадает в конечный вывод. Разве строка с заглавной буквой B не должна быть напечатана, учитывая, что обе строки Bи bbb xpzнаходятся рядом друг с другом? Если:

B ---> (empty)

и

bbb ---> xpz

пустое значение и xpzоба уникальны, поэтому обе строки должны быть напечатаны. Или я что-то упускаю?

решение1

Ответ кроется в порядке сортировки и в том, что uniqиспользует для значения поля значение, меньшее заданного номера поля ( N) при использовании -f N.

Как видно, у вас есть наборы символов ASCII, поэтому порядок сортировки вполне предсказуем:

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

Теперь давайте воспользуемся , uniq -f 1чтобы получить уникальные строки, пропуская первое поле каждой строки (разделенное пробелом) при проверке:

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

Теперь важно отметить, что uniqдля строк, имеющих меньше полей, чем указано, используется пустая строка, в данном случае 1; таким образом, все строки, имеющие только одно поле, будут рассматриваться как имеющие пустые строки для других полей при сравнении с другими строками, имеющими >=2 полей.

Итак, из sort file2.txtвывода:

b
b
B
B

все будут рассматриваться как одинаковые, и будет сохранена только первая строка, содержащая , следовательно, в выводе bбудет .b

Аналогично, из:

c
c
C

только первый из них cпопадет в uniqвывод.

решение2

Вот таблица, которая может помочь вам в этом процессе:

----------------+---------------+----------+----------------+
    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

Связанный контент