198 votes

Comment supprimer les lignes qui apparaissent sur le fichier B à partir d'un autre fichier A ?

J'ai un grand fichier A (composé de courriers électroniques), une ligne pour chaque courrier. J'ai également un autre fichier B qui contient une autre série de messages.

Quelle commande dois-je utiliser pour supprimer du fichier A toutes les adresses qui apparaissent dans le fichier B.

Ainsi, si le fichier A contient :

A
B
C

et le dossier B contenu :

B    
D
E

Dans ce cas, le fichier A devrait être laissé avec :

A
C

Je sais que c'est une question qui aurait pu être posée plus souvent, mais je n'ai trouvé que une commande en ligne qui m'a donné une erreur avec un mauvais délimiteur.

Toute aide serait très appréciée ! Quelqu'un trouvera certainement une solution intelligente, mais je ne suis pas un expert en shell.

1 votes

1 votes

La plupart des réponses ici concernent des fichiers triés, et la plus évidente est manquante, ce qui n'est bien sûr pas de votre faute, mais qui rend l'autre plus généralement utile.

8voto

peak Points 71

Cette amélioration de la réponse de @karakfa peut être sensiblement plus rapide pour les très gros fichiers. Comme pour cette réponse, aucun fichier n'a besoin d'être trié, mais la vitesse est assurée grâce aux tableaux associatifs d'awk. Seul le fichier de recherche est conservé en mémoire.

Cette formulation permet également d'envisager qu'un seul champ particulier ($N) du fichier d'entrée soit utilisé pour la comparaison.

# Print lines in the input unless the value in column $N
# appears in a lookup file, $LOOKUP;
# if $N is 0, then the entire line is used for comparison.

awk -v N=$N -v lookup="$LOOKUP" '
  BEGIN { while ( getline < lookup ) { dictionary[$0]=$0 } }
  !($N in dictionary) {print}'

(Un autre avantage de cette approche est qu'il est facile de modifier le critère de comparaison, par exemple pour supprimer les espaces blancs de début et de fin).

2voto

HelloGoodbye Points 226

Vous pouvez utiliser Python :

python -c '
lines_to_remove = set()
with open("file B", "r") as f:
    for line in f.readlines():
        lines_to_remove.add(line.strip())

with open("file A", "r") as f:
    for line in [line.strip() for line in f.readlines()]:
        if line not in lines_to_remove:
            print(line)
'

2voto

Darpan Points 709

Vous pouvez utiliser - diff fileA fileB | grep "^>" | cut -c3- > fileA

Cela fonctionnera également pour les fichiers qui ne sont pas triés.

2voto

Rafael Points 2799

Pour compléter la réponse de Python à l'utilisateur ci-dessus, voici une solution plus rapide :

    python -c '
lines_to_remove = None
with open("partial file") as f:
    lines_to_remove = {line.rstrip() for line in f.readlines()}

remaining_lines = None
with open("full file") as f:
    remaining_lines = {line.rstrip() for line in f.readlines()} - lines_to_remove

with open("output file", "w") as f:
    for line in remaining_lines:
        f.write(line + "\n")
    '

Augmenter la puissance de la soustraction des ensembles.

0voto

Pour obtenir le fichier après avoir supprimé les lignes qui apparaissent sur un autre fichier

comm -23 <(sort bigFile.txt) <(sort smallfile.txt) > diff.txt

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