Linux 中的 Uniq 命令举例说明

通过这些实际示例学习在 Unix 和 Linux 中使用 uniq 命令。

Unix 和 Linux 中的 uniq 命令用于过滤重复文本。 它可以单独使用,但通常与其他命令一起使用,例如识别文件中的冗余信息。

这是 uniq 命令的语法:

uniq [options] <input-file> <output-file>

当你在没有选项的情况下运行 uniq 时,它将使用标准输入和标准输出进行输入和输出。

虽然使用剪贴板(复制/粘贴)可以使用标准输入,但这并不是最实际的用途。

相反,您可能希望对您怀疑包含重复信息的文件使用此命令。

限制之一 独特的命令 是它只会识别文件中相邻或彼此相邻的重复项。 这很简单,但让我向您展示 example 所以你可以看到它在行动。

[[email protected] ~]$ cat apple.txt
apple
apple
orange
orange
apple 
orange
[[email protected] ~]$ uniq apple.txt 
apple
orange
apple 
orange

因此,您马上就知道您不能相信程序能够自行识别每个重复项。 有一些方法可以解决这个问题,通常是使用 sort 命令。

我将在本文后面向您展示。 首先,让我通过一些示例让您熟悉“uniq”,然后再混合其他命令并可能造成混淆。

Linux中uniq命令的7个例子

我使用了真实的系统日志,但出于演示目的对其进行了编辑。 大部分文件已经按相邻顺序排序,但我留下了几行“不合适的”来展示 uniq 命令的功能。

https://gist.github.com/abhishekpc/7dada8c6e57fd5b854f9d2dae72dddb0下载示例文本文件

示例 1:使用 uniq 命令的默认方式

尽管我已经向您展示了这一点,但让我们看看使用默认语法的示例文件。

[[email protected] ~]$ 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:将过滤结果输出到目标文件

您可能希望保存此输出,以便轻松编辑或保留它。 您可以将我们的输出定向到单独的文件,而不是普通的标准输出(终端)。 请务必注意,您不能使用此格式覆盖原始文件。

[[email protected] ~]$ uniq sample_log_file.txt uniq_log_output.txt 

这是输出文件的内容:

[[email protected] ~]$ 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’ 获取重复行数

这个选项是不言自明的。 该程序会将计数附加到每行的开头。

[[email protected] ~]$ 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 选项,则仅显示整个文件中重复的行。

[[email protected] ~]$ 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’ 打印唯一行

在这里,您将获得前一个命令的反向输出。 这些命令都不会在文件中重复。

[[email protected] ~]$ 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’ and ‘-s’]

这实际上是两个示例,但功能几乎相同。 我将解释它们是如何工作的,然后阐明它们之间的区别。

他们每个人都使用以下语法

Skip fields with:
uniq <source_file> -f N
Skip characters with:
uniq <source_file> -s N

在每个示例中,“N”是您希望跳过的项目数。 当您跳过此数量的项目时,uniq 将在该点开始比较,而不是比较整行。

选项“f”将跳过指定数量的字段。 这些字段将使用空格进行解释。

[[email protected] ~]$ cat field_separated_values.txt 
blue fish
blue fish
blue fish
blue class
red fish
green fish
two class
two class

如果要在第二列上使用 uniq 命令,则必须像这样跳过第一个字段:

[[email protected] ~]$ uniq -f1 field_separated_values.txt  
blue fish
blue class
red fish
two class

如您所见,它将“红鱼”和“绿鱼”作为同一行,因为第一个字段(带有颜色)已被忽略。 如果您在此处使用 count 选项,它将向您显示它找到的唯一行的计数:

[[email protected] ~]$ uniq -f1 -c field_separated_values.txt  
      3 blue fish
      1 blue class
      2 red fish
      2 two class

你为什么需要那个? 我会给你一个实际的场景。 许多日志文件的行首都有时间戳。 如果您只想查找此类文件中的唯一行,则可以使用 -f 选项跳过带有时间戳的第一个字段。

同样,您可以跳过特定数量的字符。

[[email protected] ~]$ uniq -s 10 field_separated_values.txt 
blue    fish

示例 7:使用 ‘-w’ 仅比较 N 个字符

‘-w’ 选项允许我们指定要在比较中使用的确切字符数。

如果您在前面的几个示例中使用了日志文件,那很好。 我想让比较文本更简单一点,以减少混淆。 如果没有,让我们把它拉回来,看看当你只使用第一个字符来查找重复项时会发生什么。

[[email protected] ~]$ 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 中使用过管道(| 字符),这是了解它们的好方法。

您可以使用管道来组合不同的命令,以节省我们的击键次数并改善我们的工作流程。 命令将按照输入的顺序执行。

这是我要使用的示例输入:

[[email protected] ~]$ cat apple.txt 
apple
orange
orange
apple
apple
banana
apple
banana

现在,让我们对输入文件进行排序,然后对其使用 uniq 命令。 排序命令重新排列文本,以便所有项目首先按相邻顺序排列。 然后当运行 uniq 命令时,它只在文件中找到 3 个唯一的行。

[[email protected] ~]$ sort apple.txt | uniq 
apple
banana
orange

如果你颠倒顺序,事情就会改变。 首先执行“uniq”命令将仅识别相邻的重复项,然后使用“sort”命令将它们按字母顺序排序。

[[email protected] ~]$ uniq apple.txt | sort
apple
apple
apple
banana
banana
orange

管道允许我们同时运行多个命令,但重要的是要考虑它们的顺序。

请注意,文件的内容保持不变,就像单独运行命令时一样。 将两个命令连接在一起也将结果保存在系统的“内存”中。 如果您单独运行它们,则除非您创建一个新文件并在运行第二个命令之前使用它覆盖原始文件的内容,否则您将无法获得这些结果。

结论

正如您可能想象的那样,这使得它成为学习中的一个重要概念 bash. 这些特定的命令(sort 和 uniq)通常一起用于从大文件(如我们的伪日志)中快速过滤信息。