linux将两各数据排序整理删除重复,linux系统利用awk 不排序删除重复行 – 运维那些事...

实例如下

1 2 3

1 2 3

1 2 4

1 2 3

1 2 5

这里假设我要处理的文件如上面的例子。不难看出里面有三行123,而我想所有的排列顺序不变,遇到重复的就自动删除。想实现的最终效果为:

1 2 3

1 2 4

1 2 5

而如果使用sort加uniq进行排序的话,这个文档是看不出有什么不妥,不过我要处理的是用户名与密码一行行对应好的,如果使用sort + uniq处理的话,用户名都排到一块了,密码也又都跑到一块了。这样就分不出来那个是那个了。 而使用的脚本很简单:

'!x[$0]++'filename

注:此处的x只是一个数据参数的名字而已,随你用a、b、c、d都行。

简要解释一下,awk 的基本执行流程是,对文件的每一行,做一个指定的逻辑判断,如果逻辑判断成立,则执行指定的命令;如果逻辑判断不成立,则直接跳过这一行。

我们这里写的 awk 命令是!x[$0]++,意思是,首先创建一个 map 叫x,然后用当前行的全文$0作为 map 的 key,到 map 中查找相应的 value,如果没找到,则整个表达式的值为真,可以执行之后的语句;如果找到了,则表达式的值为假,跳过这一行。由于表达式之后有++,因此如果某个 key 找不到对应的 value,该++操作会先把对应的 value 设成 0,然后再自增成 1,这样下次再遇到重复的行的时候,对应的 key 就能找到一个非 0 的 value 了。

注:该处的map类似于array数组,只不过在awk中叫array不恰当。

awk Oneline中我们也学到过,awk 的流程是先判断表达式,表达式为真的时候就执行语句,可是我们前面写的这个 awk 命令里只有表达式,没有语句,那我们执行什么呢?原来,当语句被省略的时候,awk 就执行默认的语句,即打印整个完整的当前行。就这样,我们通过这个非常简短的 awk 命令实现了去除重复行并保留原有文件顺序的功能。

当然,我们也可以对该例进行下改变,通过判断某列的值相同,就只保留首行。

awk '!a[$3]++' filename

删除第三列重复的行

awk '!a[$NF]++' filename

删除最后一列重复的行

如何在去除重复行时对空白行不做处理,我这里总结了三种实现方法(都是仅使用awk工具),具体如下(为了便于区分,这里我使用nl命令加了行号):

[root@u22e ~]# cat a.txt |nl -b a #原文件

1 1 2 3

2 1 2 3

3

4

5 1 2 4

6 1 2 3

7

8

9 1 2 5

[root@u22e ~]# awk '!NF || !a[$0]++' a.txt |nl -b a #方法一

1 1 2 3

2

3

4 1 2 4

5

6

7 1 2 5

[root@u22e ~]# awk '!NF {print;next} !($0 in a) {a[$0];print}' a.txt |nl -b a #方法二

1 1 2 3

2

3

4 1 2 4

5

6

7 1 2 5

[root@u22e ~]# awk '!/./ || !a[$0]++' a.txt |nl -b a #方法三

1 1 2 3

2

3

4 1 2 4

5

6

7 1 2 5

[root@u22e ~]#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值