import filecmp comparison = filecmp.dircmp(dir_local, dir_server) comparison.report_full_closure() I want to compare all CSV files kept on my local machine to files kept on a server. The folder structure is the same for both of them. I only want to do a data comparison and not metadata (like time of creation, etc). I am using filecmp but it seems to perform metadata comparison. Is there a way to do what I want?
9 Réponses :
Selon la documentation de filecmp
:
Le module filecmp définit des fonctions pour comparer des fichiers et des répertoires, avec divers compromis optionnels temps / exactitude. Pour comparer des fichiers, consultez également le module difflib.
Plus précisément, les fichiers .cmp
et .cmpfiles
comparent les fichiers à l'aide de leurs signatures, ainsi que d' autres métadonnées:
filecmp.cmp (f1, f2, peu profond = Vrai)
Comparez les fichiers nommés f1 et f2, en retournant True s'ils semblent égaux, False sinon. Si shallow est vrai, les fichiers avec des signatures os.stat () identiques sont considérés comme égaux. Sinon, le contenu des fichiers est comparé. Notez qu'aucun programme externe n'est appelé à partir de cette fonction, ce qui lui confère portabilité et efficacité. Cette fonction utilise un cache pour les comparaisons passées et les résultats, avec des entrées de cache invalides si les informations os.stat () pour le fichier changent. Le cache entier peut être effacé en utilisant clear_cache ().
filecmp.cmpfiles (dir1, dir2, commun, peu profond = Vrai)
Comparez les fichiers des deux répertoires dir1 et dir2 dont les noms sont donnés par common. Renvoie trois listes de noms de fichiers: correspondance, non-correspondance, erreurs. match contient la liste des fichiers qui correspondent, mismatch contient les noms de ceux qui ne correspondent pas, et errors répertorie les noms des fichiers qui n'ont pas pu être comparés. Les fichiers sont répertoriés dans les erreurs s'ils n'existent pas dans l'un des répertoires, si l'utilisateur n'a pas l'autorisation de les lire ou si la comparaison n'a pas pu être effectuée pour une autre raison. Le paramètre shallow a la même signification et la même valeur par défaut que pour filecmp.cmp (). Par exemple, cmpfiles ('a', 'b', ['c', 'd / e']) comparera a / c avec b / c et a / d / e avec b / d / e. «c» et «d / e» seront chacun dans l'une des trois listes renvoyées.
De plus, si vous souhaitez une sortie diff, pensez à utiliser difflib
indiqué dans la documentation de filecmp
.
filecmp: https://docs.python.org/3/library/filecmp.html
difflib: https://docs.python.org/3/library/difflib.html#module-difflib
Essayez d'utiliser git et diff.
https://gitpython.readthedocs.io/en/stable/
from git import Repo repo = Repo('my_repo') # Check differences between current files and last commit diff = repo.git.diff(repo.head.commit.tree) print(diff)
Si vous avez besoin d'une solution ponctuelle, winmerge compare des fichiers spécifiques ainsi que des répertoires entiers. La comparaison n'inclut pas les méta-informations.
Si vous avez besoin d'une solution continue, winscp est un client ftp qui peut être configuré pour comparer constamment les répertoires. Il existe probablement d'autres clients ftp qui peuvent faire cela. Et vous pouvez déplacer ou traiter des fichiers par programmation en utilisant PowerShell ou quelque chose de similaire.
Je me rends compte que ce n'est pas une réponse python, mais vous faites peut-être un travail inutile en essayant de le coder vous-même (et vous ne pourrez pas faire un meilleur travail).
Ces solutions ne font-elles pas plus que comparer et fusionner les répertoires pour que le répertoire "cible" soit mis à jour avec tous les fichiers qui se trouvent dans le répertoire "source"? Cela peut être bien plus que ce que l'OP est prêt à mâcher.
@Booboo - winmerge est manuel, vous pouvez donc faire ce que vous voulez manuellement. winscp peut être automatisé pour pousser / déplacer / écraser / alerter selon ce qui est prévu.
En regardant la comparaison des dossiers de winmerge, elle semble être basée sur les dates et les tailles des fichiers (pas ce que veut l'OP). La commande de synchronisation de WinScp a une option -preview
, mais pour autant que je -preview
elle est également basée sur des dates et / ou des tailles en fonction de la façon dont vous définissez l'option -criteria
; Je ne pense pas que WinScp puisse faire une comparaison octet par octet du contenu des fichiers.
Il existe plusieurs façons de comparer les fichiers .csv entre les 2 référentiels (système de fichiers serveur et système de fichiers local).
Méthode 1: utiliser hashlib
Cette méthode utilise le module Python hashlib. J'ai utilisé l'algorithme de hachage sha256 pour calculer le condensé de hachage des fichiers. Je compare les hachages des fichiers avec le nom exact du fichier. Cette méthode fonctionne bien, mais elle ignorera tout fichier qui n'existe pas dans les deux répertoires.
import fs import os import filecmp from google.cloud import storage def create_temp_memory_filesystem(): mem_fs = fs.open_fs('mem://') virtual_disk = mem_fs.makedir('hidden_dir') return mem_fs, virtual_disk def query_google_cloud_storage_file_by_name(filename, memory_filesystem, temp_directory): client = storage.Client.from_service_account_json('path_to_your_credentials.json') bucket = client.get_bucket('your_bucket_name') blobs = bucket.list_blobs() for blob in blobs: if blob.name == filename: with memory_filesystem.open(f'{temp_directory}/{filename}', 'w') as f: f.write(str(blob.download_to_filename(blob.name))) f.close() def compare_local_files_to_google_storage_files(local_csv_files): virtual_disk = create_temp_memory_filesystem() directory_name = str(virtual_disk[1]).split('/')[1] files = set(os.listdir(local_csv_files)) for filename in files: if filename.endswith('.csv'): local_file = f'{local_csv_files}/{filename}' query_google_cloud_storage_file_by_name(filename, virtual_disk[0], directory_name) virtual_files = virtual_disk[0].opendir(directory_name) for file_name in virtual_files.listdir('/'): comparison = filecmp.cmp(local_file, file_name, shallow=False) if comparison: print(f'The file - {filename} is identical in both the local file system and the Google Cloud bucket.') elif not comparison: print(f'The file - {filename} is different between the local file system and the Google Cloud bucket.') virtual_files.remove(file_name) virtual_disk[0].close()
Méthode 2: utiliser os st_size
Cette méthode utilise le module Python os. Dans cet exemple, j'ai comparé la taille des fichiers. Cette méthode fonctionne bien, mais elle classera mal tout fichier dont les données sont modifiées et ne modifient pas la taille du fichier.
import fs import os import hashlib from google.cloud import storage def create_temp_memory_filesystem(): mem_fs = fs.open_fs('mem://') virtual_disk = mem_fs.makedir('hidden_dir') return mem_fs, virtual_disk def query_google_cloud_storage_file_by_name(filename, memory_filesystem, temp_directory): client = storage.Client.from_service_account_json('path_to_your_credentials.json') bucket = client.get_bucket('your_bucket_name') blobs = bucket.list_blobs() for blob in blobs: if blob.name == filename: with memory_filesystem.open(f'{temp_directory}/{filename}', 'w') as f: f.write(str(blob.download_to_filename(blob.name))) f.close() def compare_local_files_to_google_storage_files(local_csv_files): virtual_disk = create_temp_memory_filesystem() directory_name = str(virtual_disk[1]).split('/')[1] files = set(os.listdir(local_csv_files)) for filename in files: if filename.endswith('.csv'): local_file_hash = hashlib.sha256(open(f'{local_csv_files}/{filename}', 'rb').read()).hexdigest() query_google_cloud_storage_file_by_name(filename, virtual_disk[0], directory_name) virtual_files = virtual_disk[0].opendir(directory_name) for file_name in virtual_files.listdir('/'): gs_file_hash = hashlib.sha256(open(file_name, 'rb').read()).hexdigest() if local_file_hash == gs_file_hash: print(f'The file - {filename} is identical in both the local file system and the Google Cloud bucket.') elif local_file_hash != gs_file_hash: print(f'The file - {filename} is different between the local file system and the Google Cloud bucket.') virtual_files.remove(file_name) virtual_disk[0].close()
Méthode 3: utiliser os st_size et st_mtime
Cette méthode utilise également le module Python os. Dans cet exemple, j'ai comparé non seulement la taille du fichier, mais également l'heure de la dernière modification. Cette méthode fonctionne bien, mais elle classera à tort les fichiers comme étant identiques. Lors des tests, j'ai enregistré un fichier sans modifications de données et os.st_mtime a marqué le fichier comme étant différent, mais en réalité ce n'était pas vraiment différent.
import fs import os import boto3 import filecmp def create_temp_memory_filesystem(): mem_fs = fs.open_fs('mem://') virtual_disk = mem_fs.makedir('hidden_dir') return mem_fs, virtual_disk def query_s3_file_by_name(filename, memory_filesystem, temp_directory): s3 = boto3.resource('s3', aws_access_key_id='your_access_key_id', aws_secret_access_key='your_secret_access_key') bucket = s3.Bucket('your_bucket_name') for obj in bucket.objects.all(): if obj.key == filename: body = obj.get()['Body'].read() with memory_filesystem.open(f'{temp_directory}/s3_{filename}', 'w') as f: f.write(str(body)) f.close() def compare_local_files_to_s3_files(local_csv_files): virtual_disk = create_temp_memory_filesystem() directory_name = str(virtual_disk[1]).split('/')[1] files = set(os.listdir(local_csv_files)) for filename in files: if filename.endswith('.csv'): local_file = f'{local_csv_files}/{filename}' query_s3_file_by_name(filename, virtual_disk[0], directory_name) virtual_files = virtual_disk[0].opendir(directory_name) for file_name in virtual_files.listdir('/'): comparison = filecmp.cmp(local_file, file_name, shallow=False) if comparison: print(f'The file - {filename} is identical in both the local file system and the S3 bucket.') elif not comparison: print(f'The file - {filename} is different between the local file system and the S3 bucket.') virtual_files.remove(file_name) virtual_disk[0].close()
Méthode 4: utilisation de set ()
Cet exemple utilise Python set () pour déterminer les différences ligne à ligne entre 2 fichiers csv du même nom. Cette méthode affichera le changement exact entre les 2 fichiers csv.
import fs import os import boto3 import hashlib def create_temp_memory_filesystem(): mem_fs = fs.open_fs('mem://') virtual_disk = mem_fs.makedir('hidden_dir') return mem_fs, virtual_disk def query_s3_file_by_name(filename, memory_filesystem, temp_directory): s3 = boto3.resource('s3', aws_access_key_id='your_access_key_id', aws_secret_access_key='your_secret_access_key') bucket = s3.Bucket('your_bucket_name') for obj in bucket.objects.all(): if obj.key == filename: body = obj.get()['Body'].read() with memory_filesystem.open(f'{temp_directory}/s3_{filename}', 'w') as f: f.write(str(body)) f.close() def compare_local_files_to_s3_files(local_csv_files): virtual_disk = create_temp_memory_filesystem() directory_name = str(virtual_disk[1]).split('/')[1] files = set(os.listdir(local_csv_files)) for filename in files: if filename.endswith('.csv'): local_file_hash = hashlib.sha256(open(f'{local_csv_files}/{filename}', 'rb').read()).hexdigest() query_s3_file_by_name(filename, virtual_disk[0], directory_name) virtual_files = virtual_disk[0].opendir(directory_name) for file_name in virtual_files.listdir('/'): s3_file_hash = hashlib.sha256(open(file_name, 'rb').read()).hexdigest() if local_file_hash == s3_file_hash: print(f'The file - {filename} is identical in both the local file system and the S3 bucket.') elif local_file_hash != s3_file_hash: print(f'The file - {filename} is different between the local file system and the S3 bucket.') virtual_files.remove(file_name) virtual_disk[0].close()
Méthode 5: utilisation de filecmp.cmp
Cette méthode utilise le module Python filecmp. Dans cet exemple, j'ai utilisé filecmp.cmp avec shallow défini sur False . La définition de ce paramètre sur False indique à filecmp d'examiner le contenu des fichiers et non les métadonnées, telles que la taille du fichier, qui est la valeur par défaut pour filecmp.cmp. Cette méthode fonctionne aussi bien que la méthode 1, qui utilisait hashlib.
import csv def get_csv_file_lines(file): with open(file, 'r', encoding='utf-8') as csv_file: rows = csv.reader(csv_file) for row in rows: yield row def compare_csv_files_line_by_line(csv_file_one, csv_file_two): csvfile_02 = get_csv_file_lines(csv_file_two) for line_one in get_csv_file_lines(csv_file_one): line_two = csvfile_02.__next__() if line_two != line_one: print('File names being compared:') print(f'csv_file_one: {csv_file_one}') print(f'csv_file_two: {csv_file_two}') print(f'The following rows have difference in the files being compared.') print('csv_file_one:', line_one) print('csv_file_two:', line_two) print('\n')
Méthode 6: utilisation de filecmp.dircmp
Cette méthode utilise également le module Python filecmp. Dans cet exemple, j'ai utilisé filecmp.dircmp , qui me permet non seulement d'identifier les fichiers qui ne sont pas communs entre les 2 répertoires et de trouver les fichiers qui ont des noms similaires, mais un contenu différent.
import filecmp def directory_recursive(directory_one, directory_two): files = filecmp.dircmp(directory_one, directory_two) for filename in files.diff_files: print(f'The file - {filename} is different in the directories - {files.left} and {files.right}') for filename in files.left_only: print(f'The file - {filename} - was only found in the directory {files.left}') for filename in files.right_only: print(f'The file - {filename} - was only found in the directory {files.right}')
Méthode 7: comparaison ligne par ligne
Cet exemple effectue une comparaison ligne par ligne de 2 fichiers csv et affiche la ligne différente. La sortie peut être ajoutée au dictionnaire Python ou au fichier JSON pour le secondaire.
import filecmp def compare_common_files(directory_one, directory_two): d1_files = set(os.listdir(directory_one)) d2_files = set(os.listdir(directory_two)) common_files = list(d1_files & d2_files) if common_files: for filename in common_files: file_01 = f'{directory_one}/{filename}' file_02 = f'{directory_two}/{filename}' comparison = filecmp.cmp(file_01, file_02, shallow=False) if comparison: print(f'The file - {filename} is identical in the directories - {directory_one} and {directory_two}') elif not comparison: print(f'The file - {filename} is different in the directories - {directory_one} and {directory_two}')
Système de fichiers local vers un compartiment S3 à l'aide de hashlib
L'exemple ci-dessous est un cas d'utilisation réel pour comparer des fichiers entre un système de fichiers local et un compartiment S3 distant. À l'origine, j'allais utiliser object.e_tag créé par AWS S3, mais cette balise peut avoir des problèmes et ne doit pas être utilisée dans une opération de comparaison de hachage. J'ai décidé d'interroger S3 et de charger un fichier individuel dans un système de fichiers mémoire qui pourrait être interrogé et vidé lors de chaque opération de comparaison. Cette méthode a très bien fonctionné et n'a aucun impact négatif sur les performances de mon système.
import os def compare_common_files_by_lines(directory_one, directory_two): d1_files = set(os.listdir(directory_one)) d2_files = set(os.listdir(directory_two)) common_files = list(d1_files & d2_files) if common_files: for filename in common_files: if fileName.endswith('.csv'): file_01 = open(f'{directory_one}/{filename}', 'r', encoding='ISO-8859-1') file_02 = open(f'{directory_two}/{filename}', 'r', encoding='ISO-8859-1') csv_file_01 = set(map(tuple, csv.reader(file_01))) csv_file_02 = set(map(tuple, csv.reader(file_02))) different = csv_file_01 ^ csv_file_02 for row in sorted(different, key=lambda x: x, reverse=True): if row: print(f'This row: \n {row} \n was different between the file {fileName} in the directories' f' {directory_one} and {directory_two}')
Système de fichiers local vers le compartiment S3 à l'aide de filecmp
Cet exemple est le même que celui ci-dessus, sauf que j'utilise filecmp.cmp au lieu de hashlib pour l'opération de comparaison.
import os def compare_common_files_by_metadata(directory_one, directory_two): d1_files = set(os.listdir(directory_one)) d2_files = set(os.listdir(directory_two)) common_files = list(d1_files & d2_files) if common_files: for filename in common_files: file_01 = os.stat(f'{directory_one}/{filename}') file_02 = os.stat(f'{directory_two}/{filename}') if file_01.st_size == file_02.st_size and file_01.st_mtime == file_02.st_mtime: print(f'The file - {filename} is identical in the directories {directory_one} and {directory_two}') elif file_01.st_size != file_02.st_size or file_01.st_mtime != file_02.st_mtime: print(f'The file - {filename} is different in the directories {directory_one} and' f' {directory_two}')
Système de fichiers local vers le bucket de stockage Google Cloud à l'aide de hashlib
Cet exemple est similaire à l'exemple de code hashlib S3 ci-dessus, mais il utilise un compartiment de stockage Google Cloud.
import os def compare_common_files_by_size(directory_one, directory_two): d1_files = set(os.listdir(directory_one)) d2_files = set(os.listdir(directory_two)) common_files = list(d1_files & d2_files) if common_files: for filename in common_files: file_01 = os.stat(f'{directory_one}/{filename}') file_02 = os.stat(f'{directory_two}/{filename}') if file_01.st_size == file_02.st_size: print(f'The file - {filename} is identical in the directories {directory_one} and {directory_two}') elif file_01.st_size != file_02.st_size: print(f'The file - {filename} is different in the directories {directory_one} and' f' {directory_two}')
Système de fichiers local vers le bucket de stockage Google Cloud à l'aide de filecmp
Cet exemple est similaire à l'exemple de code S3 filecmp ci-dessus, mais il utilise un bucket de stockage Google Cloud.
import hashlib def compare_common_files_by_hash(directory_one, directory_two): d1_files = set(os.listdir(directory_one)) d2_files = set(os.listdir(directory_two)) common_files = list(d1_files & d2_files) if common_files: for filename in common_files: hash_01 = hashlib.sha256(open(f'{directory_one}/{filename}', 'rb').read()).hexdigest() hash_02 = hashlib.sha256(open(f'{directory_two}/{filename}', 'rb').read()).hexdigest() if hash_01 == hash_02: print(f'The file - {filename} is identical in the directories {directory_one} and {directory_two}') elif hash_01 != hash_02: print(f'The file - {filename} is different in the directories {directory_one} and {directory_two}')
shallow (facultatif): Une valeur booléenne «Vrai» ou «Faux». La valeur par défaut de ce paramètre est True. Si sa valeur est True, seules les métadonnées des fichiers sont comparées. Si False, le contenu des fichiers est comparé.
import filecmp # Path of first file file1 = "/home/geeks/Desktop/gfg/data.txt" # Path of second file file2 = "/home/geeks/Desktop/gfg/gfg.txt" # Compare the os.stat() # signature i.e the metadata # of both files comp = filecmp.cmp(file1, file2) # Print the result of comparison print(comp) # Compare the # contents of both files comp = filecmp.cmp(file1, file2, shallow = False) # Print the result of comparison print(comp)
Le problème est que filecmp.dircmp
effectue une comparaison superficielle :
La classe dircmp compare les fichiers en effectuant des comparaisons superficielles comme décrit pour filecmp.cmp ()
Une comparaison superficielle signifie que filecmp
vérifiera si le fichier A et le fichier B os.stat sont égaux. Dans ce cas, il renvoie vrai. Si faux, il compare ensuite les contenus A et B et retourne vrai s'ils sont égaux, et faux dans le cas contraire.
Pour ignorer os.stat , vous pouvez utiliser filecmp.cmpfiles(dir1, dir2, common, shallow=False)
. Notez que filecmp.cmpfiles
fonctionne comme suit:
Comparez les fichiers des deux répertoires dir1 et dir2 dont les noms sont donnés par common .
Vous pouvez en savoir plusici .
De plus, vous pouvez parcourir en boucle tous les fichiers à l'intérieur de dir1 et dir2 , et pour chacun d'eux exécutez filecmp.cmp(f1, f2, shallow=False)
. Vous pouvez en savoir plus sur filecmp.cmp
ici .
Si vous avez des doutes sur la façon dont fonctionne peu profond , cette réponse pourrait vous aider.
C'est rapide, sale et gourmand en ressources;) Si vous êtes sous Linux, appelez diff
, si vous êtes sous Windows, appelez fc
. Autrement dit, si vous voulez simplement savoir s'ils ont les mêmes données. Vous devez être en mesure d'accéder aux fichiers `` à partir du serveur '' localement, alors téléchargez-les et mettez-les dans un bac une fois que vous avez comparé - ou montez un lecteur partagé si cela est possible. Comme vous allez comparer les données partout où votre code s'exécute, vous devez soit télécharger vos données, soit télécharger les données du serveur de toute façon, alors tirez-les simplement vers le bas et mettez-les dans le bac lorsque vous avez terminé. par exemple sous windows:
import subprocess def files_are_a_match(file1, file2): """function returns True for matching files. False on mismatch or error. Expects windows file paths as strings""" try: cmd = f"fc /B \"{file1}\" \"{file2}\"" txt = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True) except: return False return "FC: no differences encountered" in str(txt)
Une meilleure approche pour obtenir un «n'est-ce pas la même chose? La réponse serait de générer un hachage des fichiers, si vous avez le contrôle du serveur, vous le feriez là-bas, et le vôtre localement, puis comparez les hachages (moins de données volantes). Mais ce n'est pas clair quelle est votre intention ou quel est votre contrôle sur le serveur.
Voici une façon de comparer le contenu des fichiers CSV.
Importez des packages et créez deux fonctions:
local_dir = Path('../../../projects') start = perf_counter() local_hashes = csv_hashes(local_dir) elapsed = perf_counter() - start rate = len(local_hashes) / elapsed print(f'indexed {rate:.3f} files/sec') indexed 53.342 files/sec ## too slow for real-world use case?
Spécifiez le répertoire de niveau supérieur et créez le nom du fichier: valeur de hachage dict sur la machine locale.
import hashlib from pathlib import Path from time import perf_counter def sha256sum(filename): ''' source: https://stackoverflow.com/a/44873382/13608599 ''' h = hashlib.sha256() b = bytearray(128 * 1024) mv = memoryview(b) with open(filename, 'rb', buffering=0) as f: for n in iter(lambda : f.readinto(mv), 0): h.update(mv[:n]) return h.hexdigest() def csv_hashes(dir_name): ''' Map CSV filenames to SHA hashes. ''' return { csv_file: sha256sum(csv_file) for csv_file in dir_name.rglob('*.csv') }
Répétez sur la machine distante et comparez les deux dictionnaires.
Ce programme utilise le package pysftp
du référentiel PyPI
. Il parcourt récursivement le répertoire local à la recherche de fichiers csv. Pour chaque fichier trouvé, il calcule le chemin dans le répertoire distant du fichier csv distant correspondant et l'utilisation de pysftp
teste d'abord si le fichier distant existe ou non. Si le fichier existe, le fichier est lu. pysftp
(et le protocole sftp 3 en général) ne prend en charge que la lecture binaire. On suppose donc que le contenu du fichier peut être décodé en utilisant utf-8
. Les fichiers locaux et distants sont «normalisés» pour tenir compte du fait que différentes conventions de fin de ligne peuvent être utilisées pour les deux fichiers si différentes plates-formes OS sont utilisées avant d'être comparées. Les fichiers sont ensuite comparés pour l'égalité. Vous pouvez, bien entendu, modifier la façon dont la sortie doit être affichée.
#!/usr/bin/env python3 import pysftp import sys from pathlib import Path from io import BytesIO import re LOCAL_DIR = 'C:\\My\\Directory\\' # with closing separator REMOTE_DIR = '/home/directory/' # absolute directory with closing separator class Sftp: def __init__(self, host, port, username, password, deploymentDirectory, verbose=True): if deploymentDirectory[-1] != '/': deploymentDirectory += '/' self.deployment_directory = deploymentDirectory self.verbose = verbose self.connection = None try: self.connection = pysftp.Connection(host, port=port, username=username, password=password) except Exception: print('Could not connect to remote sftp server with the specified arguments.', file=sys.stderr) sys.exit(1) def __del__(self): self.close() def close(self): if self.connection: self.connection.close() self.connection = None def read_text_file(self, remote_file_name): full_remote_file_name = self.deployment_directory + remote_file_name b = BytesIO() self.connection.getfo(full_remote_file_name, b) s = b.getvalue().decode('utf-8') return s def remote_file_exists(self, remote_file_name): full_remote_file_name = self.deployment_directory + remote_file_name return self.connection.isfile(full_remote_file_name) def compare(local_text, remote_text): """ The files could be the same except for the way the hosts handle the line-termination sequence (Windows: \r\n, Unix/Linux: \n, Mac: \r). So, let's normalize: """ rex = re.compile(r'\r\n?') local_text = rex.sub('\n', local_text) remote_text = rex.sub('\n', remote_text) return local_text == local_text def main(): sftp = Sftp(host='demo.com', port=22, username='xxxx', password='xxxx', deploymentDirectory=REMOTE_DIR) l_local_dir = len(LOCAL_DIR) for path in Path(LOCAL_DIR).rglob('*.csv'): dir, file_name = path.parent, path.name # compute relative remote path: remote_file_name = str(dir)[l_local_dir:].replace('\\', '/') + '/' + file_name if not sftp.remote_file_exists(remote_file_name): print(f'{path}: This file does not exist in remote directory.') else: remote_text = sftp.read_text_file(remote_file_name) with path.open(encoding='utf-8') as f: local_text = f.read() if compare(local_text, remote_text): print(f'{path} exits in the remote directory and matches.') else: print(f'{path} exits in the remote directory but does not match.') sftp.close() main()
Avez-vous essayé
difflib
?