2017-08-06 1 views
1

tout le monde! Je souhaite supprimer les doublons et conserver les lignes avec la valeur la plus élevée d'une colonne (4ème colonne) dans un fichier avec 4 champs. Je dois le faire sur un serveur Linux.Supprimer les doublons et garder la ligne qui contient la valeur maximale d'une colonne - LINUX

Avant

gene subj e-value ident 
    g1 h1 0.05 75.5 
    g1 h2 0.03 60.6 
    g2 h7 0.00 80.5 
    g2 h9 0.00 50.3 
    g2 h4 0.03 90.7 
    g3 h5 0.10 30.5 
    g3 h8 0.00 76.8 
    g4 h11 0.00 80.7 

Après

gene subj e-value ident 
    g1 h1 0.05 75.5 
    g2 h4 0.03 90.7 
    g3 h8 0.00 76.8 
    g4 h11 0.00 80.7 

Merci beaucoup et je suis désolé si je demandais quelque chose répété! Mais je n'ai pas trouvé de réponse à mon problème.

+2

qu'avons u essayé? – tso

+0

J'ai essayé des commandes basées sur awk, comme 'cat blast_selected_split0_outfmt6.txt | awk -F '\ t' '{if ($ 1 $ 3 en a) {if ($ 7> a [$ 1 $ 3]) {a [$ 1 $ 3] = $ 7; r [$ 1 $ 3] = $ 0;}} sinon if ($ 3 $ 1 dans a) {if ($ 7> a [$ 3 $ 1]) {a [$ 3 $ 1] = $ 7; r [$ 3 $ 1] = $ 0;}} else {a [$ 1 $ 3] = $ 7; r [$ 1 $ 3] = $ 0;}} FIN {pour (x en r) imprimer r [x]} '' –

+0

Mais il a gardé des doublons –

Répondre

2

Vous pouvez essayer cela, s'il est pas de problème pour obtenir la sortie sans l'en-tête:

tail -n +2 file.txt | sort -k1,1 -k4,4rn | sort -uk1,1 

Explication:

tail -n +2 file.txt 

va supprimer les en-têtes afin qu'ils ne sont pas impliqués dans tout le tri.

sort -k1,1 -k4,4rn 

triera par la colonne 1 première (-k1,1), puis par la colonne 4 numériquement et dans l'ordre inverse (-k4,4rn)

Enfin:

sort -uk1,1 

supprimera les doublons en prenant en compte seulement la première colonne. Sachez que -k1,1 signifie de la première colonne à la première colonne, donc -k4,4 est de la colonne 4 à la colonne 4. Ajustez pour s'adapter à vos colonnes.

+0

Merci beaucoup! Les doublons ont été enlevés, mais ils n'ont pas eu la meilleure valeur dans la septième colonne. En fait, mon fichier est plus grand que l'exemple (il a 7 colonnes), j'ai simplifié dans un fichier à 4 colonnes. J'ai donc utilisé cette commande: 'tail -n +2 file.txt | trier -k1,1 -k4,4rn | sorte -uk1,1'. Y a-t-il quelque chose qui ne va pas? –

+0

@ M.Sobreiro Mis à jour ma réponse pour ajouter une explication, j'espère que cela vous aide. Je pense que ce que vous voulez, c'est 'tail -n +2 file.txt | trier -k1,1 -k7,7rn | sorte -uk1,1' – archemiro

+0

Merci pour votre attention et votre aide !!! –

0

Avec GNU datamash outil:

datamash --headers -Wfs -g1 max 4 < file | cut -f1-4 

La sortie:

gene subj e-value ident 
g1 h1 0.05  75.5 
g2 h4 0.03  90.7 
g3 h8 0.00  76.8 
g4 h11 0.00  80.7 
+0

Merci! J'essaierai!! –

0

Une solution awk, mais j'aime la version archimiro pour plus de simplicité.

awk ' 
    NR>1 && $1 in arr { 
     if ($4 > arr[$1][4]) 
      split($0, arr[$1]) 
     next 
    } 

    NR>1 { 
     arr[$1][1] = "" 
     split($0, arr[$1]) 
    } 

    END { 
     for(i in arr) { 
      for(j in arr[i]) 
       printf arr[i][j] "\t" 
      print "" 
     } 
    } 
' data.file 

Le résultat:

g1 h1 0.05 75.5  
g2 h4 0.03 90.7  
g3 h8 0.00 76.8  
g4 h11 0.00 80.7  
+0

Merci beaucoup !!! –