Supprimer les champs en double dans une colonne donnée (après vérification de l'identité)

Je voudrais retirer d'une colonne donnée ($ 2 dans l'exemple) les champs en double (séparés par des virgules), mais seulement si la colonne ID ($ 1 dans l'exemple) est la même.

Consortingbution:

A 1,2,3,4 A 8,9,10,11 A 2,3,4,11,12 B 4,5,6,7 B 6,8,9,10 

Production attendue:

 A 1,2,3,4 A 8,9,10,11 A 12 B 4,5,6,7 B 8,9,10 

C'est assez facile dans awk utilisant un tableau , split , et une boucle régulière:

 { split($2, elements, ",") out = "" for (i in elements) { el = elements[i] key = $1 " " el if (!(key in used)) { out = out el "," } used[key] = 1 } sub(/,$/, "", out) $2 = out } 1 

Pour chaque ligne, nous divisons la deuxième colonne par des virgules et sauvegardons les bits dans un tableau. Nous construisons ensuite la nouvelle valeur pour cette colonne avec une boucle, vérifiant si nous avons vu la valeur avant ou non.

Nous conservons l'set de valeurs que nous avons déjà vu dans le tableau (associatif) used . Nous construisons une key string contenant à la fois la valeur de la première colonne et la valeur de la seconde que nous recherchons actuellement. Si la key est used , nous avons vu celle-ci avant pour cet ID et ne devrait pas la mettre dans la sortie; sinon, c'est nouveau, et nous concaténerons la valeur. Pour que nous ne l'utilisions plus, nous stockons la key (qui sera quelque chose comme " A 3 ") dans notre set d'éléments visibles.

Enfin, nous remettons la list construite dans la deuxième colonne. C'est essentiellement l'approche que vous adopteriez dans n'importe quelle autre langue.

Placez le code ci-dessus dans un file et exécutez-le avec awk -f , ou indiquez-le comme un argument sur la command line.

 perl -lpe 's/(\S+)\s+\K\S+/join ",", grep {!$seen{$1}->{$_}++} split ",", $&/e'