Задав вопрос на 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