183 votes

Existe-t-il un moyen d'unifier par colonne ?

J'ai un fichier .csv comme celui-ci :

stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1
overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0
overflow@domain2.com,2009-11-27 00:58:29.646465785,2x3.net,256.255.255.0
...

Je dois supprimer les e-mails similaires (la ligne entière) dans le fichier. Le problème est de savoir comment utiliser 'uniq' sur le champ 1 (séparé par une virgule) ? Selon le manuel, uniq n'a pas d'options pour les colonnes.

J'ai essayé quelque chose avec sort | uniq mais ça ne marche pas :/ Merci,

308voto

Carl Smotricz Points 36400
sort -u -t, -k1,1 file
  • -u pour un unique
  • -t, donc la virgule est le délimiteur
  • -k1,1 pour le champ clé 1

Résultat du test :

overflow@domain2.com,2009-11-27 00:58:29.793000000,xx3.net,255.255.255.0 
stack2@domain.com,2009-11-27 01:05:47.893000000,xx2.net,127.0.0.1

96voto

ghostdog74 Points 86060
awk -F"," '!_[$1]++' file
  • -F définit le séparateur de champs.
  • $1 est le premier champ.
  • _[val] lever les yeux val dans le hachage _ (une variable régulière).
  • ++ incrémenter, et retourner l'ancienne valeur.
  • ! renvoie un non logique.
  • il y a une impression implicite à la fin.

15voto

Prakash Points 579

Considérer la colonne multiple.

Trier et donner une liste unique basée sur la colonne 1 et la colonne 3.

sort -u -t : -k 1,1 -k 3,3 test.txt

-t : = les deux points sont des séparateurs

-k 1,1 -k 3,3 = basé sur la colonne 1 et la colonne 3

9voto

Carsten C. Points 93

Ou si vous voulez utiliser l'uniq :

cat mycvs.cvs | tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2

donne :

1 01:05:47.893000000 2009-11-27 tack2@domain.com
2 00:58:29.793000000 2009-11-27 overflow@domain2.com
1

-3voto

Steve B. Points 23227

Bien, plus simple que d'isoler la colonne avec awk, si vous avez besoin de supprimer tout ce qui a une certaine valeur pour un fichier donné, pourquoi ne pas simplement faire grep -v :

Par exemple, pour supprimer tout ce qui a la valeur "col2" en deuxième position ligne : col1,col2,col3,col4

grep -v ',col2,' file > file_minus_offending_lines

Si cela n'est pas suffisant, parce que certaines lignes peuvent être incorrectement dépouillées en faisant apparaître la valeur correspondante dans une colonne différente, vous pouvez faire quelque chose comme ceci :

awk pour isoler la colonne incriminée : par exemple

awk -F, '{print $2 "|" $line}'

le -F définit le champ délimité par ",", $2 signifie colonne 2, suivi d'un délimiteur personnalisé, puis de la ligne entière. Vous pouvez alors filtrer en supprimant les lignes qui commencer avec la valeur incriminée :

 awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE

et ensuite on enlève ce qui se trouve avant le délimiteur :

awk -F, '{print $2 "|" $line}' | grep -v ^BAD_VALUE | sed 's/.*|//g'

(note - la commande sed est peu soignée car elle n'inclut pas les valeurs d'échappement. Aussi, le motif sed devrait être quelque chose comme "[^|]+" (c'est-à-dire tout ce qui n'est pas le délimiteur). Mais j'espère que c'est assez clair.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X