Использование 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