J'ai mes références sous forme de fichier texte avec une longue liste d'entrées et chacune a deux (ou plus) champs.
La première colonne est l'URL de la référence; la deuxième colonne est le titre qui peut varier un peu selon la façon dont la saisie a été effectuée. Idem pour le troisième champ qui peut ou non être présent.
Je veux identifier mais pas supprimer les entrées dont le premier champ (URL de référence) est identique. Je sais sort -k1,1 -u
mais cela supprimera automatiquement (de manière non interactive) tout sauf le premier hit. Existe-t-il un moyen de me le faire savoir afin que je puisse choisir lequel conserver?
Dans l'extrait ci-dessous de trois lignes qui ont le même premier champ ( http://unix.stackexchange.com/questions/49569/
), je voudrais garder la ligne 2 car elle a des balises supplémentaires (tri, CLI) et supprimer les lignes # 1 et # 3:
http://unix.stackexchange.com/questions/49569/ unique-lines-based-on-the-first-field
http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field sort, CLI
http://unix.stackexchange.com/questions/49569/ Unique lines based on the first field
Existe-t-il un programme pour aider à identifier ces "doublons"? Ensuite, je peux nettoyer manuellement en supprimant personnellement les lignes # 1 et # 3?
la source
Réponses:
Si je comprends votre question, je pense que vous avez besoin de quelque chose comme:
ou:
où
file.txt
est votre fichier contenant des données vous concernant.Dans la sortie, vous verrez le nombre de lignes et de lignes où le premier champ est trouvé deux fois ou plus.
la source
cut -d " " -f1 file.txt | uniq -d
me donne même une belle sortie.Il s'agit d'un problème classique qui peut être résolu avec la
uniq
commande.uniq
peut détecter les lignes consécutives en double et supprimer les doublons (-u
,--unique
) ou ne conserver que les doublons (-d
,--repeated
).Étant donné que la commande de lignes en double n'est pas importante pour vous, vous devez d'abord la trier. Utilisez ensuite
uniq
pour imprimer uniquement des lignes uniques:Il existe également une option
-c
(--count
) qui imprime le nombre de doublons pour l'-d
option. Voir la page de manuel deuniq
pour plus de détails.Si vous ne vous souciez vraiment pas des pièces après le premier champ, vous pouvez utiliser la commande suivante pour rechercher des clés en double et imprimer chaque numéro de ligne (ajoutez-en une autre
| sort -n
pour que la sortie soit triée par ligne):Étant donné que vous souhaitez voir les lignes en double (en utilisant le premier champ comme clé), vous ne pouvez pas utiliser directement
uniq
. Le problème qui rend l'automatisation difficile est que les parties du titre varient, mais un programme ne peut pas déterminer automatiquement quel titre doit être considéré comme le dernier.Voici un script AWK (enregistrez-le
script.awk
) qui prend votre fichier texte en entrée et imprime toutes les lignes en double afin que vous puissiez décider lequel supprimer. (awk -f script.awk yourfile.txt
)la source
-w
(--check-chars
) pour limiter à un nombre fixe de caractères, mais vu votre exemple, vous avez des premiers champs variables. Étant donnéuniq
que ne prend pas en charge la sélection de champs, vous devez utiliser une solution de contournement. Je vais inclure un exemple AWK car c'est plus facile.-w
mais la longueur du premier champ est variable :(Si je lis bien, tout ce dont vous avez besoin est quelque chose comme
Cela affichera le numéro de la ligne qui contient la dupe et la ligne elle-même. Par exemple, en utilisant ce fichier:
Il produira cette sortie:
Pour imprimer uniquement le numéro de la ligne, vous pouvez faire
Et pour imprimer uniquement la ligne:
Explication:
Le
awk
script imprime simplement le 1er champ séparé par des espaces du fichier. Utilisez$N
pour imprimer le champ Nième.sort
le trie etuniq -c
compte les occurrences de chaque ligne.Ceci est ensuite passé à la
while
boucle qui enregistre le nombre d'occurrences as$num
et la ligne as$dupe
et if$num
est supérieure à un (donc il est dupliqué au moins une fois), il recherchera le fichier pour cette ligne, en utilisant-n
pour imprimer le numéro de ligne. Le--
indiquegrep
que ce qui suit n'est pas une option de ligne de commande, utile pour quand$dupe
peut commencer-
.la source
Sans doute le plus verbeux de la liste, pourrait probablement être plus court:
donne sur un fichier texte comme:
une sortie comme:
Une fois que vous avez choisi les lignes à supprimer:
la source
Voir les éléments suivants triés
file.txt
:Parce que la liste est courte, je peux voir (après tri) qu'il y a trois ensembles de doublons.
Ensuite, par exemple, je peux choisir de conserver:
plutôt que
Mais pour une liste plus longue, ce sera difficile. Sur la base des deux réponses, l'une suggérant
uniq
et l'autre suggérantcut
, je trouve que cette commande me donne la sortie que j'aimerais:la source
cut
. Si vous effectuez un travail de déduplication, les numéros de ligne peuvent être très utiles. Pour imprimer tous les doublons, utilisez l'-D
option au lieu de-d
.for dup in $(cut -d " " -f1 file.txt | uniq -d); do grep -n $dup file.txt; done
comme dans ma réponse. Cela vous donnera un meilleur aperçu de ce qui vous intéresse.Voici comment je l'ai résolu:
file_with_duplicates:
Fichier trié et dédupliqué par les colonnes 1 et 2:
Fichier trié uniquement par les colonnes 1 et 2:
Afficher uniquement la différence:
la source