我有文件:
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