使用 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

和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 没有出现在最终输出中。考虑到行Bbbb 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

相关内容