想要重复 awk 时的最后一行吗?

想要重复 awk 时的最后一行吗?

我有文件:

key value

blah blah
blah blah
blahblah
man1 boy1
blah blah
man1 boy2
man1 boy1

我这样做是为了删除重复的行:

awk '/man1/ { print $1,$2} ' file | awk '!x[$0]++'

该命令获取第一行并忽略其他行

man1 boy1 
man1 boy2

但我想忽略除最后一行之外的所有行:

man1 boy2 
man1 boy1

正如拉梅什所说,我想要这样的东西:

cat filename
blah blah
blah blah
blahblah
man1 boy1
blah blah
man1 boy2
man1 boy1
man1 boy2
man1 boy3
man1 boy4
man1 boy2

所需的输出

man1 boy1
man1 boy3
man1 boy4
man1 boy2

答案1

tac filename |awk '/man1/ { print $1,$2} '| awk '!x[$0]++' | tac 

测试

我想用更具体的输入进行测试。所以,我的测试如下。

cat filename
blah blah
blah blah
blahblah
man1 boy1
blah blah
man1 boy2
man1 boy1
man1 boy2
man1 boy3
man1 boy4
man1 boy2

现在,我运行上面的命令并得到输出,

tac filename |awk '/man1/ { print $1,$2} '| awk '!x[$0]++' | tac
man1 boy1
man1 boy3
man1 boy4
man1 boy2

根据 Steeldriver 的建议,我们可以将其修改awk为更简单,如下所示:

tac filename | awk '/^man1/ && !x[$2]++' | tac

答案2

你可以使用这个 shell 脚本来做到这一点:

#!/bin/bash
awk '/man1/{pos[$0] = NR}
END {
  for(key in pos) reverse[pos[key]] = key
  for(nr=1;nr<=NR;nr++)
    if(nr in reverse) print reverse[nr]
}' yourfile

输出:

[root@host ~]# sh shell.sh
man1 boy1
man1 boy3
man1 boy4
man1 boy2

来源

答案3

zsh

$ printf '%s\n' ${(Oau)${(MOa)${(f)"$(<file)"}:#man1*}}
man1 boy1
man1 boy3
man1 boy4
man1 boy2

那些是参数扩展标志:

  • f: 在换行符上分割
  • ${(M)array:#pattern}:扩展到与模式匹配的元素
  • Oa: 颠倒数组的顺序
  • u: 独特的

答案4

两遍解决方案。在第一遍中,将每个键的最后一条记录的记录号捕获到一个数组中。在第二遍中,如果数组中存在记录号,则打印

awk 'NR == FNR{if ($0 ~ /man/)x[$0]=NR; next};
     FNR == 1{for (k in x) y[x[k]]=k};
     (FNR in y)' file file
man1 boy1
man1 boy3
man1 boy4
man1 boy2

相关内容