J'ai des données tabulaires qui ressemblent à ceci.
$ perl -e '%seen = (); for (<>) { @v = split(/\s+/); unless (exists($seen{$v[1]})) { $seen{$v[1]} = 1; print } }' < data.tsv > data.clean.tsv
Je dois supprimer des lignes du tableau afin qu'aucune valeur ne soit dupliquée dans la deuxième colonne (date) - seulement la première l'occurrence doit rester.
Je n'ai pas utilisé Perl depuis un certain temps, mais après quelques recherches sur Google pour me rappeler la syntaxe correcte, j'ai pu trouver cette ligne unique.
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
Après un rapide coup d'œil, cela semble faire l'affaire, mais c'est un gâchis. Y a-t-il un moyen plus propre et plus concis de faire cela en utilisant des commandes shell portables (UNIX), ou une solution va-t-elle impliquer un désordre de Perl / sed / awk / etc.
3 Réponses :
Perl a anticipé des problèmes comme celui-ci et a proposé des solutions concises:
$ 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
Voir perlrun
pour plus d'informations sur les commutateurs -a
et -n
.
Avec le Module B :: Deparse
, vous pouvez voir comment Perl étend les commutateurs de ligne de commande en quelque chose qui ressemble à votre script d'origine.
perl -ane 'print unless $seen{$F[1]}++' < data.csv > data.clean.csv
Pas besoin d'être en désordre
perl -ne'print unless $exists{(split)[1]}++' dup_data.txt
Puisque data.tsv est déjà trié sur le champ 2nd , une méthode plus simple, pas de perl
nécessaire:
1f2edc31defc588a369544ac32215afec2ae65da 2019-01-08 e95c31b76be6b99eb8a0670b93b91c9e9abf2efb 2018-11-27 c6b6b534addff919150d94276f61eb8d0882f3f6 2018-09-04 459a495a929cffa2205d31c6cc7ba2750af2580b 2018-06-25 0970c0fef779a4ea89638140f339c2047d10d0c5 2017-12-29
Utilisation de bash
pour comparer au code OP: cmp <(perl -e '% vu = (); for (<>) {@v = split (/ \ s + /); sauf (existe ($ vu {$ v [1]})) {$ vu {$ v [1]} = 1; print}} '
0
( i.e. true, les sorties sont les mêmes).
Veuillez inclure la sortie souhaitée.