Unix 和 Linux 中的 Uniq 命令:7 个基本示例
Linux 和 Unix 中的 uniq 命令用于从文件中删除重复行。通过这些示例了解如何使用 uniq 命令。
通过这些实际示例学习在 Unix 和 Linux 中使用 uniq 命令。
Unix 和 Linux 中的 uniq 命令用于过滤重复文本。它可以单独使用,但通常与其他命令一起使用,例如识别文件中的冗余信息。
这是 uniq 命令的语法:
uniq [options] <input-file> <output-file>
当您在不带选项的情况下运行 uniq 时,它将使用 stdin 和 stdout 进行输入和输出。
虽然可以使用剪贴板(复制/粘贴)来使用标准输入,但这并不是最实际的用途。
相反,您可能希望对您怀疑包含重复信息的文件使用此命令。
uniq 命令的一个限制是它只能识别文件中相邻或相邻的重复项。这非常简单,但让我向您展示一个示例,以便您可以看到它的实际效果。
[linux@fedora ~]$ cat apple.txt
apple
apple
orange
orange
apple
orange
[linux@fedora ~]$ uniq apple.txt
apple
orange
apple
orange
因此,您立即知道您不能相信该程序能够自行识别每个重复项。有一些方法可以解决这个问题,通常是使用 sort 命令。
我将在本文后面向您展示。首先,让我通过一些示例来让您熟悉“uniq”,然后再混合其他命令和可能令人困惑的事情。
Linux 中 uniq 命令的 7 个示例
我使用了真实的系统日志,但出于演示目的对其进行了编辑。文件的大部分内容已按相邻顺序排序,但我“不合适”地留下了几行来显示 uniq 命令的功能。
https://gist.github.com/abhishekpc/7dada8c6e57fd5b854f9d2dae72dddb0下载示例文本文件
示例1:使用uniq命令默认方式
尽管我已经向您展示了这一点,但让我们使用默认语法查看示例文件。
[linux@fedora ~]$ uniq sample_log_file.txt
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
/usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
你可以看到很多重复的行被合并了,但仍然有冗余信息。这是由于我已经描述过的功能限制。让我们再看几个示例,并检查“uniq”命令行实用程序中内置的一些选项。
示例2:将过滤结果输出到目标文件
您可能想要保存此输出,以便可以轻松地编辑或保留它。您可以将我们的输出定向到单独的文件,而不是普通的标准输出(终端)。需要注意的是,您不能使用此格式覆盖原始文件。
[linux@fedora ~]$ uniq sample_log_file.txt uniq_log_output.txt
这是输出文件的内容:
[linux@fedora ~]$ cat uniq_log_output.txt
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
/usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
示例 3:使用“-c”获取重复行数
这个选项是非常不言自明的。该程序会将计数附加到每行的开头。
[linux@fedora ~]$ uniq sample_log_file.txt -c
2 /usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
2 /usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
1 /usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
2 /usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
5 /usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
1 /usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
7 /usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
1 PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
8 wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
示例 4:仅使用“-d”打印重复行
正如您所看到的,如果您使用 uniq 命令的 -d 选项,则仅显示整个文件中重复的行。
[linux@fedora ~]$ uniq sample_log_file.txt -d
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
示例 5:仅使用“-u”打印唯一的行
在这里,您将获得上一个命令的逆输出。文件中没有重复这些命令。
[linux@fedora ~]$ uniq sample_log_file.txt -u
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
/usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
示例 6:使用 uniq [‘-f’ 和 ‘-s’] 忽略字段或字符
这实际上是两个示例,但功能几乎相同。我将解释它们是如何工作的,然后澄清它们两者之间的差异。
他们每个人都使用以下语法
Skip fields with:
uniq <source_file> -f N
Skip characters with:
uniq <source_file> -s N
在每个示例中,“N”是您希望跳过的项目数。当您跳过此数量的项目时,uniq 将在该点开始比较,而不是比较整行。
选项“f”将跳过指定数量的字段。这些字段将使用空格进行解释。
[linux@fedora ~]$ cat field_separated_values.txt
blue fish
blue fish
blue fish
blue class
red fish
green fish
two class
two class
如果您想在第二列上使用 uniq 命令,则必须跳过第一个字段,如下所示:
[linux@fedora ~]$ uniq -f1 field_separated_values.txt
blue fish
blue class
red fish
two class
正如您所看到的,它将“红鱼”和“绿鱼”视为同一行,因为第一个字段(带有颜色)已被忽略。如果您在此处使用 count 选项,它将显示它找到的唯一行的数量:
[linux@fedora ~]$ uniq -f1 -c field_separated_values.txt
3 blue fish
1 blue class
2 red fish
2 two class
你为什么需要那个?我给你一个实际的场景。许多日志文件在行的开头都有时间戳。如果您只想查找此类文件中的唯一行,则可以使用 -f 选项跳过带有时间戳的第一个字段。
同样,您可以跳过特定数量的字符。
[linux@fedora ~]$ uniq -s 10 field_separated_values.txt
blue fish
示例 7:使用“-w”仅比较 N 个字符
“-w”选项允许我们指定在比较中使用的确切字符数。
如果您在前几个示例中使用了日志文件,那就没问题。我想让比较文本更简单一些,以减少混乱。如果没有,让我们把它拉回来,看看当你只使用第一个字符来查找重复项时会发生什么。
[linux@fedora ~]$ uniq -w 4 sample_log_file.txt
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
从程序的角度来看,所有以“/usr”开头的行现在都被标识为“相同”。
如果您正在寻找特定的日志事件,这可能会很有帮助。
奖励:同时使用“sort”和“uniq”避免不完整的匹配。
您可以单独运行这些命令来达到相同的效果,但如果您从未在 Linux 中使用过管道(| 字符),那么这是了解它们的好方法。
您可以使用管道来组合不同的命令,以节省我们的击键次数并改进我们的工作流程。命令将按照键入的顺序执行。
这是我要使用的示例输入:
[linux@fedora ~]$ cat apple.txt
apple
orange
orange
apple
apple
banana
apple
banana
现在,让我们对输入文件进行排序,然后对其使用 uniq 命令。 sort 命令重新排列文本,使所有项目首先按相邻顺序排列。然后,当运行 uniq 命令时,它在文件中仅找到 3 个唯一行。
[linux@fedora ~]$ sort apple.txt | uniq
apple
banana
orange
如果你颠倒顺序,事情就会改变。首先执行“uniq”命令将仅识别相邻的重复项,然后使用“sort”命令将它们按字母顺序排序。
[linux@fedora ~]$ uniq apple.txt | sort
apple
apple
apple
banana
banana
orange
管道允许我们同时运行多个命令,但考虑它们的顺序很重要。
请注意,文件的内容保持不变,就像单独运行命令时一样。将两个命令连接在一起还将结果保留在系统的“内存”中。如果单独运行它们,则无法获得这些结果,除非您创建一个新文件并在运行第二个命令之前使用它覆盖原始内容。
结论
正如您可能想象的那样,这是学习 bash 的一个重要概念。这些特定的命令(sort 和 uniq)经常一起使用来快速过滤大文件(如伪日志)中的信息。