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

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

file1.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

и file2.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 оба уникальны, поэтому обе строки должны быть напечатаны. Или я что-то упустил?

2 ответа

Ответ лежит в порядке сортировки и что делает 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выходной.

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

----------------+---------------+----------+----------------+
    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
Другие вопросы по тегам