我有一些像这样的表格数据。
1f2edc31defc588a369544ac32215afec2ae65da 2019-01-08
e95c31b76be6b99eb8a0670b93b91c9e9abf2efb 2018-11-27
c2dd1d6be6434b6ef109fa0394546fa500501efe 2018-11-27
c6b6b534addff919150d94276f61eb8d0882f3f6 2018-09-04
459a495a929cffa2205d31c6cc7ba2750af2580b 2018-06-25
11f7883b29295e39bc964522deb96132d6a2803e 2018-06-25
73a2a72ee9d0a9acf0ed02b0959f3fb5a44c3fc7 2018-06-25
0970c0fef779a4ea89638140f339c2047d10d0c5 2017-12-29
我需要从表中删除行,以便在第二(日期)列中没有重复的值-仅应保留第一次出现的情况。
我已经有一段时间没有使用Perl了,但是经过几个Google搜索以提醒自己正确的语法后,我才提出了这种单行代码。
$ perl -e '%seen = (); for (<>) { @v = split(/\s+/); unless (exists($seen{$v[1]})) { $seen{$v[1]} = 1; print } }' < data.tsv > data.clean.tsv
乍一看,这似乎可以解决问题,但这是一团糟。是否有一种更简洁的方法来使用可移植(UNIX)Shell命令来执行此操作,或者是否有任何解决方案都涉及到Perl / sed / awk / etc等问题?
答案 0 :(得分:2)
不需要凌乱
perl -ne'print unless $exists{(split)[1]}++' dup_data.txt
答案 1 :(得分:1)
Perl预料到了这样的问题,并提出了简洁的解决方案:
perl -ane 'print unless $seen{$F[1]}++' < data.csv > data.clean.csv
有关-a
和-n
开关的信息,请参见perlrun
。
借助有用的B::Deparse
模块,您可以了解Perl如何将命令行开关扩展为类似于原始脚本的内容。
$ perl -MO=Deparse -ane 'print unless $seen{$F[1]}++'
LINE: while (defined($_ = <ARGV>)) {
our(@F) = split(' ', $_, 0);
print $_ unless $seen{$F[1]}++;
}
-e syntax OK
答案 2 :(得分:1)
由于 data.tsv 已经在 2nd 字段上进行了排序,这是一种更简单的方法,因此不需要perl
:
uniq -f 1 data.tsv > data.clean.tsv
输出,( data.clean.tsv 的内容):
1f2edc31defc588a369544ac32215afec2ae65da 2019-01-08
e95c31b76be6b99eb8a0670b93b91c9e9abf2efb 2018-11-27
c6b6b534addff919150d94276f61eb8d0882f3f6 2018-09-04
459a495a929cffa2205d31c6cc7ba2750af2580b 2018-06-25
0970c0fef779a4ea89638140f339c2047d10d0c5 2017-12-29