在 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
和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
和bbb xpz
彼此相邻,不应该打印大写字母 B 的行吗?如果:
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