J'ai un fichier .csv comme celui-ci:
stack2@example.com,2009-11-27 01:05:47.893000000,example.net,127.0.0.1
overflow@example.com,2009-11-27 00:58:29.793000000,example.net,255.255.255.0
overflow@example.com,2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...
Je dois supprimer les e-mails en double (toute la ligne) du fichier (c'est-à-dire l'une des lignes contenant [email protected]
dans l'exemple ci-dessus). Comment utiliser uniq
uniquement le champ 1 (séparé par des virgules)? Selon man
, uniq
n'a pas d'options pour les colonnes.
J'ai essayé quelque chose avec sort | uniq
mais ça ne marche pas.
man sort
). Il représente la position de départ et d'arrêt.sort
dit la page de manuel: "-u
,--unique
avec-c
, vérifiez un ordre strict; sans-c
, sortez uniquement le premier d'une exécution égale ." Il s'agit donc bien "de la première occurrence du doublon avant tri".-F
définit le séparateur de champ.$1
est le premier champ._[val]
rechercheval
dans le hachage_
(une variable régulière).++
incrémenter et retourner l'ancienne valeur.!
renvoie non logique.la source
awk -F',' '{ x[$1]=$0 } END { for (i in x) print x[i] }' file
!_[$1][$2]++
peut être utilisé pour trier par les deux premiers champs.awk
Cependant, mon -fu n'est pas assez fort pour être unique sur une gamme de domaines. :(Pour considérer plusieurs colonnes.
Trier et donner une liste unique basée sur la colonne 1 et la colonne 3:
-t :
deux points est séparateur-k 1,1 -k 3,3
basé sur la colonne 1 et la colonne 3la source
ou si vous voulez utiliser uniq:
<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
donne:
la source
cat
! Plutôt que de canaliser dans tr, laissez simplement tr lire le fichier en utilisant<
. Le pipingcat
est une complication inutile courante utilisée par les novices. Pour de grandes quantités de données, il doit y avoir un effet sur les performances.rev
.Si vous souhaitez conserver le dernier des doublons que vous pourriez utiliser
Quelle était mon exigence
ici
tac
inversera le fichier ligne par lignela source
Voici une façon très astucieuse.
Formatez d'abord le contenu de telle sorte que la colonne à comparer pour son caractère unique soit une largeur fixe. Une façon de procéder consiste à utiliser awk printf avec un spécificateur de largeur de champ / colonne ("% 15s").
Maintenant, les options -f et -w de uniq peuvent être utilisées pour ignorer les champs / colonnes précédents et pour spécifier la largeur de comparaison (largeur de colonne (s)).
Voici trois exemples.
Dans le premier exemple ...
1) Faites temporairement de la colonne d'intérêt une largeur fixe supérieure ou égale à la largeur maximale du champ.
2) Utilisez l'option -f uniq pour ignorer les colonnes précédentes et utilisez l'option -w uniq pour limiter la largeur à tmp_fixed_width.
3) Supprimer les espaces de fin de la colonne pour "restaurer" sa largeur (en supposant qu'il n'y avait pas d'espaces de fin au préalable).
Dans le deuxième exemple ...
Créer une nouvelle colonne uniq 1. Retirez-la ensuite après l'application du filtre uniq.
Le troisième exemple est le même que le second, mais pour plusieurs colonnes.
la source
eh bien, plus simple que d'isoler la colonne avec awk, si vous devez supprimer tout avec une certaine valeur pour un fichier donné, pourquoi ne pas simplement faire grep -v:
par exemple pour tout supprimer avec la valeur "col2" dans la deuxième ligne: col1, col2, col3, col4
Si cela ne suffit pas, car certaines lignes peuvent être supprimées de manière incorrecte en affichant éventuellement la valeur correspondante dans une autre colonne, vous pouvez faire quelque chose comme ceci:
awk pour isoler la colonne incriminée: par exemple
le -F définit le champ délimité à ",", $ 2 signifie la colonne 2, suivi d'un délimiteur personnalisé puis de la ligne entière. Vous pouvez ensuite filtrer en supprimant les lignes commençant par la valeur incriminée:
puis retirez le contenu avant le délimiteur:
(notez que la commande sed est bâclée car elle n'inclut pas les valeurs d'échappement. De plus, le modèle sed devrait vraiment ê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.
la source
En triant le fichier avec d'
sort
abord, vous pouvez ensuite postuleruniq
.Il semble bien trier le fichier:
Vous pouvez également faire de la magie AWK:
la source
sort
, alorsuniq
,sort
doit être fait avant de faireuniq
sinon cela ne fonctionne pas (mais vous pouvez ignorer la deuxième commande et simplement utilisersort -u
). Deuniq(1)
: "Filtrer les lignes correspondantes adjacentes depuis INPUT (ou entrée standard), en écrivant vers OUTPUT (ou sortie standard)."