2017-05-02 4 views
-3

j'ai un onglet très grand fichier séparé, une partie qui ressemble à ceci:tri et de uniquize un onglet fichier séparé pour deux colonnes

33 x 171 297 126 
4 x 171 300 129 
2 x 171 303 132 
11 y 163 289 126 
5 y 163 290 127 
3 y 163 291 128 
2 y 163 292 129 
2 y 170 289 119 
2 z 166 307 141 
2 z 166 308 142 
6 z 166 309 143 
4 z 166 329 163 
2 z 166 330 164 

je veux trier et sélectionner une seule ligne pour chaque: x , y, z basée sur la valeur la plus élevée associée à la première colonne (en unix)

+4

Qu'avez-vous essayé? – kabanus

+0

Donc, vous attendriez '33 x ...', '11 y ...', et '6 z ...'? –

+0

Essayez ceci: 'perl -lanE '($ v, $ k) = @ F [0..1]; $ h {$ k} = $ _, $ j {$ k} = $ v si $ j {$ k} <$ v; END {dis pour les valeurs% h} 'file' –

Répondre

1

vous pouvez le faire avec awk:

awk ' 
{ 
    key = $2; 
    flag = 0; 
    if (key in value) { max = value[key] ; flag = 1 }; 
    if (flag == 0 || max < $1) { value[key] = $1; line[key] = $0 }; 
} 
END { 
    for (key in line) { print line[key] }; 
} 
' data.tsv 
+0

Vous n'avez pas besoin du drapeau et max. Enlevez les lignes 2 et 3 du premier bloc et remplacez le si dans la ligne 4 par 'if (value [key] <$ 1)'. – ULick

+0

@ULick si la première colonne contient des nombres négatifs, votre version pourrait ne pas fonctionner correctement (les valeurs par défaut sont 0 et ""). – Andrey

+0

True. Peut être résolu par 'if (! (Valeur clé) || $ 1> valeur [clé])'. Toujours pas de drapeau, mais perdre la lisibilité. – ULick