Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

วิธีเปรียบเทียบไฟล์ใน Python


ปัญหา

คุณต้องเปรียบเทียบไฟล์ใน Python

วิธีแก้ปัญหา..

โมดูล filecmp ใน python สามารถใช้เพื่อเปรียบเทียบไฟล์และไดเร็กทอรี 1.

cmp(file1, file2[, shallow])

filecmp เปรียบเทียบไฟล์ file1 และ file2 และคืนค่า True ถ้าเหมือนกัน False ถ้าไม่ โดยค่าเริ่มต้น ไฟล์ที่มีคุณสมบัติเหมือนกันตามที่ส่งคืนโดย os.stat() จะถือว่าเท่ากัน หากไม่ระบุแบบตื้น (หรือเป็นจริง) ไฟล์ที่มีลายเซ็นสถิติเหมือนกันจะถือว่าเท่าเทียมกัน

cmpfiles(dir1, dir2, common[, shallow])

เปรียบเทียบเนื้อหาของไฟล์ที่อยู่ในรายการทั่วไปในสองไดเร็กทอรี dir1 และ dir2 cmpfiles ส่งคืนทูเพิลที่มีสามรายการ - ตรงกัน ไม่ตรงกัน ข้อผิดพลาดของชื่อไฟล์

  • ตรงกัน - แสดงรายการไฟล์ที่เหมือนกันในทั้งสองไดเร็กทอรี

  • ไม่ตรงกัน - แสดงรายการไฟล์ที่ไม่ตรงกัน

  • ข้อผิดพลาด - แสดงรายการไฟล์ที่ไม่สามารถเปรียบเทียบได้ด้วยเหตุผลบางประการ

dircmp(dir1, dir2 [, ignore[, hide]])

สร้างอ็อบเจ็กต์การเปรียบเทียบไดเร็กทอรีที่สามารถใช้เพื่อดำเนินการเปรียบเทียบต่างๆ บนไดเร็กทอรี dir1 และ dir2

  • ละเว้น - ละเว้นรายชื่อไฟล์ที่จะละเว้น ค่าเริ่มต้นของ ['RCS','CVS','tags']

  • ซ่อน - รายการชื่อไฟล์ที่จะซ่อน รายการเริ่มต้น [os.curdir, os.pardir] (['.', '..'] บน UNIX

อินสแตนซ์ของ filecmp.dircmp ใช้วิธีการต่อไปนี้เพื่อพิมพ์รายงานอย่างละเอียดไปยัง sys.stdout:

  • report() :พิมพ์การเปรียบเทียบระหว่างสองไดเร็กทอรี

  • report_partial_closure() :พิมพ์การเปรียบเทียบของสองไดเร็กทอรีเช่นเดียวกับไดเร็กทอรีย่อยในทันทีของ directories.

  • report_full_closure() :พิมพ์การเปรียบเทียบของสองไดเร็กทอรี ไดเร็กทอรีย่อยทั้งหมด ไดเร็กทอรีย่อยทั้งหมดของ those subdirectories, and so on (i.e., recursively).

  • left_list:ไฟล์และไดเรกทอรีย่อยที่พบในไดเรกทอรี path1 ไม่รวมองค์ประกอบของรายการที่ซ่อน

  • right_list:ไฟล์และไดเรกทอรีย่อยที่พบในไดเรกทอรี path2 ไม่รวมองค์ประกอบของรายการที่ซ่อน

  • ทั่วไป:ไฟล์และไดเร็กทอรีย่อยที่อยู่ในทั้งไดเร็กทอรี path1 และไดเร็กทอรี path2

  • left_only:ไฟล์และไดเร็กทอรีย่อยที่อยู่ในไดเร็กทอรี path1 เท่านั้น

  • right_only:ไฟล์และไดเร็กทอรีย่อยที่อยู่ในไดเร็กทอรี path2 เท่านั้น

  • common_dirs:ไดเร็กทอรีย่อยที่อยู่ในไดเร็กทอรี path1 และ directory path2

  • common_files:ไฟล์ที่อยู่ในไดเร็กทอรี path1 และ directory path2

  • same_files:พาธไปยังไฟล์ที่มีเนื้อหาเหมือนกันทั้งในไดเร็กทอรี path1 และ directory path2

  • diff_files:พาธไปยังไฟล์ที่อยู่ในทั้งไดเร็กทอรี path1 และไดเร็กทอรี path2 แต่มีเนื้อหาต่างกัน

  • funny_files:พาธไปยังไฟล์ที่อยู่ในทั้งไดเร็กทอรี path1 และไดเร็กทอรี path2 แต่ไม่สามารถเปรียบเทียบได้ด้วยเหตุผลบางประการ

  • subdirs:พจนานุกรมที่จับคู่ชื่อใน common_dirs กับอ็อบเจ็กต์ dircmp

กำลังเตรียมข้อมูลการทดสอบเพื่อเปรียบเทียบ

import os
# prepare test data
def makefile(filename,text=None):
"""
Function: make some files
params : input file, body
"""

with open(filename, 'w') as f:
f.write(text or filename)

return

# prepare test data
def makedirectory(directory_name):
"""
Function: make directories
params : input directory
"""
if not os.path.exists(directory_name):
os.mkdir(directory_name)


# Get current working directory
present_directory = os.getcwd()

# change to directory provided
os.chdir(directory_name)

# Make two directories
os.mkdir('dir1')
os.mkdir('dir2')

# Make two same subdirectories
os.mkdir('dir1/common_dir')
os.mkdir('dir2/common_dir')

# Make two different subdirectories
os.mkdir('dir1/dir_only_in_dir1')
os.mkdir('dir2/dir_only_in_dir2')

# Make a unqiue file one each in directory
makefile('dir1/file_only_in_dir1')
makefile('dir2/file_only_in_dir2')

# Make a unqiue file one each in directory
makefile('dir1/common_file', 'Hello, Writing Same Content')
makefile('dir2/common_file', 'Hello, Writing Same Content')

# Make a non unqiue file one each in directory
makefile('dir1/not_the_same')
makefile('dir2/not_the_same')

makefile('dir1/file_in_dir1', 'This is a file in dir1')

os.mkdir('dir2/file_in_dir1')

os.chdir(present_directory)

return

if __name__ == '__main__':
os.chdir(os.getcwd())
makedirectory('example')
makedirectory('example/dir1/common_dir')
makedirectory('example/dir2/common_dir')
  • ตัวอย่าง filecmp ตัวอย่างการรัน filecmp อาร์กิวเมนต์ตื้นบอก cmp() ว่าจะดูเนื้อหาของไฟล์หรือไม่ นอกเหนือจากข้อมูลเมตาของไฟล์

ค่าดีฟอลต์คือการเปรียบเทียบแบบตื้นโดยใช้ข้อมูลที่มีอยู่จาก os.stat() หากผลลัพธ์เหมือนกัน ไฟล์จะถือว่าเหมือนกัน ดังนั้น ไฟล์ที่มีขนาดเท่ากันที่สร้างพร้อมกันจะถูกรายงานเป็นไฟล์เดียวกัน แม้ว่าจะมีเนื้อหาต่างกัน

เมื่อตื้นเป็นเท็จ เนื้อหาของไฟล์จะถูกเปรียบเทียบเสมอ

import filecmp

print('Output \n *** Common File :', end=' ')

print(filecmp.cmp('example/dir1/common_file',
'example/dir2/common_file'), end=' ')

print(filecmp.cmp('example/dir1/common_file',
'example/dir2/common_file', shallow=False))

print(' *** Different Files :', end=' ')

print(filecmp.cmp('example/dir1/not_the_same',
'example/dir2/not_the_same'), end=' ')

print(filecmp.cmp('example/dir1/not_the_same',
'example/dir2/not_the_same', shallow=False))

print(' *** Identical Files :', end=' ')

print(filecmp.cmp('example/dir1/file_only_in_dir1',
'example/dir1/file_only_in_dir1'), end=' ')

print(filecmp.cmp('example/dir1/file_only_in_dir1',
'example/dir1/file_only_in_dir1', shallow=False))

ผลลัพธ์

*** Common File : True True
*** Different Files : False False
*** Identical Files : True True
  • cmpfiles ตัวอย่าง:

ใช้ cmpfiles() เพื่อเปรียบเทียบชุดของไฟล์ในสองไดเร็กทอรีโดยไม่เรียกซ้ำ

import filecmp

import os

# Determine the items that exist in both directories.
dir1_contents = set(os.listdir('example/dir1'))
dir2_contents = set(os.listdir('example/dir2'))
common = list(dir1_contents & dir2_contents)

common_files = [f for f in common if os.path.isfile(os.path.join('example/dir1', f))]

print(f' *** Common files are : {common_files}')

# Now, let us compare the directories
match, mismatch, errors = filecmp.cmpfiles(
'example/dir1',
'example/dir2',
common_files,)

print(f' *** Matched files are : {match}')
print(f' *** mismatch files are : {mismatch}')
print(f' *** errors files are : {errors}')
*** Common files are : ['file_in_dir1', 'not_the_same', 'common_file']
*** Matched files are : ['common_file']
*** mismatch files are : ['file_in_dir1', 'not_the_same']
*** errors files are : []

7.เปรียบเทียบไดเร็กทอรี

import filecmp
dc = filecmp.dircmp('example/dir1', 'example/dir2')
print(f"output \n *** Printing detaile report: \n ")
print(dc.report())
print(f"\n")
print(dc.report_full_closure())

ผลลัพธ์

*** Printing detaile report:

diff example/dir1 example/dir2
Only in example/dir1 : ['dir_only_in_dir1', 'file_only_in_dir1']
Only in example/dir2 : ['dir_only_in_dir2', 'file_only_in_dir2']
Identical files : ['common_file']
Differing files : ['not_the_same']
Common subdirectories : ['common_dir']
Common funny cases : ['file_in_dir1']
None

diff example/dir1 example/dir2
Only in example/dir1 : ['dir_only_in_dir1', 'file_only_in_dir1']
Only in example/dir2 : ['dir_only_in_dir2', 'file_only_in_dir2']
Identical files : ['common_file']
Differing files : ['not_the_same']
Common subdirectories : ['common_dir']
Common funny cases : ['file_in_dir1']

diff example/dir1\common_dir example/dir2\common_dir
Common subdirectories : ['dir1', 'dir2']

diff example/dir1\common_dir\dir1 example/dir2\common_dir\dir1
Identical files : ['common_file', 'file_in_dir1', 'file_only_in_dir1', 'not_the_same']
Common subdirectories : ['common_dir', 'dir_only_in_dir1']

diff example/dir1\common_dir\dir1\common_dir example/dir2\common_dir\dir1\common_dir

diff example/dir1\common_dir\dir1\dir_only_in_dir1 example/dir2\common_dir\dir1\dir_only_in_dir1

diff example/dir1\common_dir\dir2 example/dir2\common_dir\dir2
Identical files : ['common_file', 'file_only_in_dir2', 'not_the_same']
Common subdirectories : ['common_dir', 'dir_only_in_dir2', 'file_in_dir1']

diff example/dir1\common_dir\dir2\common_dir example/dir2\common_dir\dir2\common_dir

diff example/dir1\common_dir\dir2\dir_only_in_dir2 example/dir2\common_dir\dir2\dir_only_in_dir2

diff example/dir1\common_dir\dir2\file_in_dir1 example/dir2\common_dir\dir2\file_in_dir1
None

คุณสามารถลองใช้คำสั่งทั้งหมดที่กล่าวถึงใน Point1 เพิ่มเติมเพื่อดูว่าแต่ละวิธีทำงานอย่างไร