J'ai un gros fichier A (composé d'e-mails), une ligne pour chaque e-mail. J'ai aussi un autre fichier B qui contient un autre ensemble de mails.
Quelle commande utiliserais-je pour supprimer toutes les adresses qui apparaissent dans le fichier B du fichier A.
Donc, si le fichier A contenait:
A
B
C
et le fichier B contenait:
B
D
E
Ensuite, le fichier A doit être laissé avec:
A
C
Maintenant, je sais que c'est une question qui aurait pu être posée plus souvent, mais je n'ai trouvé qu'une seule commande en ligne qui m'a donné une erreur avec un mauvais délimiteur.
Toute aide serait très appréciée! Quelqu'un va sûrement proposer un one-liner intelligent, mais je ne suis pas l'expert des coquilles.
Réponses:
Si les fichiers sont triés (ils le sont dans votre exemple):
-23
supprime les lignes qui se trouvent dans les deux fichiers, ou uniquement dans le fichier 2. Si les fichiers ne sont pas triés, passez-les d'sort
abord ...Voir la page de manuel ici
la source
comm -23 file1 file2 > file3
affichera le contenu du fichier1 pas du fichier2, vers le fichier3. Et puismv file3 file1
effacerait enfin le contenu redondant dans file1.comm -23 file1 file2 | sponge file1
. Aucun nettoyage nécessaire.grep -Fvxf <lines-to-remove> <all-lines>
Exemple:
Production:
Explication:
-F
: utilisez des chaînes littérales au lieu du BRE par défaut-x
: ne considère que les correspondances qui correspondent à la ligne entière-v
: impression non correspondante-f file
: prendre des modèles du fichier donnéCette méthode est plus lente sur les fichiers pré-triés que les autres méthodes, car elle est plus générale. Si la vitesse compte également, voir: Un moyen rapide de trouver des lignes dans un fichier qui ne sont pas dans un autre?
Voici une automatisation rapide pour le fonctionnement en ligne:
GitHub en amont .
usage:
Voir aussi: /unix/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another
la source
awk à la rescousse!
Cette solution ne nécessite pas d'entrées triées. Vous devez d'abord fournir fileB.
Retour
Comment ça marche?
Notez que cela peut maintenant être utilisé pour supprimer les mots de la liste noire.
avec un léger changement, il peut nettoyer plusieurs listes et créer des versions nettoyées.
la source
A\nC
, écrivez d'abord dans un fichier temporaire et écrasez le fichier d'origine... > tmp && mv tmp fileA
fileB
n'est pas vide (0 octet de long), car si c'est le cas, vous obtiendrez un résultat vide au lieu du contenu attendu defileA
. (Cause:FNR==NR
s'appliquera à ce moment-fileA
là.)Une autre façon de faire la même chose (nécessite également une entrée triée):
Dans Bash, si les fichiers ne sont pas pré-triés:
la source
Vous pouvez le faire à moins que vos fichiers ne soient triés
--new-line-format
est pour les lignes qui sont dans le fichier b mais pas dans a--old-..
est pour les lignes qui sont dans le fichier a mais pas dans b--unchanged-..
est pour les lignes qui sont dans les deux.%L
fait en sorte que la ligne soit imprimée exactement.pour plus de détails
la source
comm
commande.comm
exige que les fichiers soient triés, donc s'ils sont triés, vous pouvez également utiliser cette solution. Vous pouvez utiliser cette solution indépendamment du fait que le fichier soit trié ou nonCe raffinement de la bonne réponse de @ karakfa peut être nettement plus rapide pour les fichiers très volumineux. Comme pour cette réponse, aucun des fichiers n'a besoin d'être trié, mais la vitesse est assurée grâce aux tableaux associatifs de awk. Seul le fichier de recherche est conservé en mémoire.
Cette formulation permet également la possibilité qu'un seul champ particulier ($ N) dans le fichier d'entrée soit utilisé dans la comparaison.
(Un autre avantage de cette approche est qu'il est facile de modifier le critère de comparaison, par exemple pour couper les espaces blancs de début et de fin.)
la source
Vous pouvez utiliser Python:
la source
Vous pouvez utiliser -
diff fileA fileB | grep "^>" | cut -c3- > fileA
Cela fonctionnera également pour les fichiers qui ne sont pas triés.
la source
Pour supprimer les lignes communes entre deux fichiers, vous pouvez utiliser la commande grep, comm ou join.
Cela affiche les lignes du fichier1 qui ne correspondent à aucune ligne du fichier2.
Cela affiche les lignes du fichier1 qui ne correspondent à aucune ligne du fichier2.
la source