|
uniq 命令用从给定输入中来找出唯一的行,而忽略或排除掉重复的行,当然反过来也可以找到重复的行而去掉唯一的行。需要注意的是,uniq 只能应用于被排序了的文本(参考 sort 命令),因此 uniq 大多数情况下总是和 sort命令搭配使用。
比如对于下面的一个文本:# cat tmp.txt
welcome
groad
to
www
groad
net 里面的有一个重复行 groad,如果直接对该文件使用 uniq 命令,那么会毫无改变的输出:# cat tmp.txt
welcome
groad
to
www
groad
net 如果我们将重复的 groad 放到一起:# cat tmp.txt
welcome
to
www
groad
groad
net 然后再直接对其使用 uniq 命令,那么会看到: # uniq tmp.txt
welcome
to
www
groad
net 上面发现,重复的一行 groad 被去掉了。
如果希望只打印出唯一而没有重复的行,可用 -u 选项:# uniq -u tmp.txt
welcome
to
www
net
像前面所说,uniq 命令只对排序后的文件起作用,因此假如上面的 tmp.txt 文件若是还没有被排序,那么我们可以:
类似地,如果只想列出重复的行,那么使用 -d 选项:
还可以使用 -c 选项对每一行的行数进行统计:# uniq -c tmp.txt
1 welcome
1 to
1 www
2 groad
1 net
另外还有 -s 和 -w 这两个选项经常会结合使用,其中:
-s 表示指定忽略前面几个字符;
-w 表示最大比较多少个字符。
下面是重新设计的一个文本:# cat temp.txt
a:01:linux
b:03:unix
c:01:windows
b:04:ucosii
a:03:macios 对上面的文本直接用 sort :# sort temp.txt
a:01:linux
a:03:macios
b:03:unix
b:04:ucosii
c:01:windows 我们可以将排序的结果通过管道使用 uniq 的 -w 选项:# sort temp.txt | uniq -s 2 -w 2
a:01:linux
a:03:macios
b:04:ucosii
c:01:windows 由上面输出可见,当排序后的内容通过管道后,首先被 -s 的选项要求忽略前面的 2 个字符,接着又被要求最大比较 2 个字符,因此这里实际比较的是 01, 03 这些数字是否发生重复,正如上面所见,有两个 03 的行排在一块,即发生了重复,因此得到了上面的输出。
此外,uniq 的 -z 选项会使 uniq 的输出是以 '\0' 结尾的,使用该选项的目的往往是在下一步的处理中将该处理结果通过管道输送到 xargs 命令中。如果没有 '\0' 作为结尾,那么对于 xargs 来说,空格字符就是默认的间隔符,这样在解析中就容易出现错误。比如 "welcome to groad" 会被 xargs 认为是 3 个独立的参数,但当这个字符串以 '\0' 作为结尾,那么它就会被认为是单独的一个参数。比如:uniq -z tmp.txt | xargs -0 rm -f
关于 xargs 命令中的 -0 选项及更多信息可参考:http://www.groad.net/bbs/read.php?tid-498.html
下面的例子中,我们用 uniq 结合其它命令来统计一个字符串中重复的字符个数,假设有一个字符串为:akoqaaboooozkk 。
如下运行命令:# echo "akoqaaboooozkk" | sed 's/[^\n]/&\n/g' | sed '/^$/d' | sort | uniq -c
3 a
1 b
3 k
5 o
1 q
1 z 还可以进一步写成:# echo "akoqaaboooozkk" | sed 's/[^\n]/&\n/g' | sed '/^$/d' | sort | uniq -c | tr -d ' \n'
3a1b3k5o1q1z 在上面的命令中,当字符串通过管道后,sed 查找只要非换行字符,找到后使用 &\n 进行替换,其中 & 表示匹配非换行部分,即保留该字符,因此 &\n 表示在保留的字符后再添加一个换行。在这样处理后,最后还会产生一个换行,亦即一个空行,因此让它再次通过管道用 sed 删除掉。然后使用 sort 进行排序,最后用 uniq 的 -c 选项统计重复的个数。这个统计重复字符的方法称为“分解统计法”。 |
|