昨天有个同事谈到一个笔试题:
用shell在一个文件中找出出现次数top50的50个单词, 前提是在这个文件中每行只有一个单词.
我们几个讨论了一下, 第一感觉都是用最熟悉的grep, 但要实现起来怕是得很多代码. 晚上回家没事瞎逛, 看到网友在某篇技术博客里提到uniq命令, 以前竟然不知道这个command, 请原谅我的无知...我搜了下用法, 让我立刻意识到这个笔试题可以秒答...
uniq
顾名思义, 这个command就是要列出不重复的项(使唯一). 以前一直感觉shell没有set这个数据类型很不方便, 现在完全可以用此命令来弥补了. 需要注意的是: uniq只比较相邻两项, 也就是说隔行的重复, TA是不care的. 这个时候就需要配合sort命令.
参数如下:
-u: 列出若干唯一项. 应该u是取得uniq的意思.
-d: 列出若干重复项. 应该d是取得disable uniq的意思.
-f n: 忽略前n个字段再来做比较. f means fields. 字段间的分隔符是空格或者TAB. 从0开始计数. 与-n等价.
-s n: 忽略前n个字符. s means characters. 从0开始计数. 与+n等价.
-i: 忽略大小写. i means ignore case.
-c: 计数. c means count.
我来举个例子:
我有个文件名字是testfile
foo
bar
foo
bar
haha
haha
hehe
cat testfile | uniq
foo
bar
foo
bar
haha
hehe
我们可以看到少了一个haha. foo和bar却还是有重复项. 这就是我前面提到的注意点. 要确保重复项相邻.
cat testfile | sort | uniq -c
2 bar
2 foo
2 haha
1 hehe
这下就把所有重复项给去掉了, 顺便计了个数.
我们再来看-f和-s. 先改下testfile:
1st foo
2nd bar
3rd foo
4th bar
5th haha
6th haha
7th hehe
cat testfile | uniq -f 1
1st foo
2nd bar
3rd foo
4th bar
5th haha
7th hehe
是不是和第一个例子的结果一样, 少了一个haha.
同样的, 忽略前3个字符(从0开始), 结果是一样的.
cat testfile | uniq -s 3
1st foo
2nd bar
3rd foo
4th bar
5th haha
7th hehe
-u和-d根据字面意思理解就好啦, 应该没什么gap, 这里就不举例子了.
最后说下sort, 上面也有用到, 名字起的好, 一下就明白了. TA有挺多参数的, 改天另写一篇介绍下. 回到开头的笔试题, 会用到-r参数, 就是reverse的意思. 说到这里想必你也能秒答这个笔试题了吧:)
网友评论