Linux

如何列出在某個文件夾中出現但不在另一個文件夾中的所有文件?

  • February 18, 2021

我有一個包含很多子文件夾和文件的文件夾(我們稱之為“orig”),另一個文件夾中有很多相同的文件作為備份放置在不同的文件夾結構中(我們稱之為“備份”)。我想列出“備份”中所有“原始”中尚不存在的文件,以便我可以將它們放在“原始”中正確的子文件夾中並刪除“備份”。按文件名和大小進行比較就足夠了。

之前也有人問過類似的問題,推薦的解決方案是diff -qr orig/ backup/。但是,當我嘗試這樣做時,我發現遞歸不起作用,因為該命令列出了出現在一個但不是另一個中的文件夾,而不是文件。這是一個例子。首先,我創建了兩個文件夾,每個文件夾都有一個子文件夾和一個文件,其中每個子文件夾和文件都有不同的內容:

$ mkdir orig
$ mkdir backup
$ mkdir orig/1
$ mkdir backup/2
$ echo 'blah' > orig/1/test.txt
$ ls orig/1
test.txt
$ echo 'blah1' > backup/2/test1.txt

現在我使用“-qr”選項比較它們:

$ diff -qr orig/ backup/
Only in orig/: 1
Only in backup/: 2

如果我進入其中一個子文件夾,則會找到該文件夾中的文件:

$ diff -r orig/1 backup/
Only in backup/: 2
Only in orig/1: test.txt

實際上,無論有沒有’-qr’,我都會得到相同的行為。這是一個錯誤還是我誤解了差異?我正在使用 diff (GNU diffutils) 3.7。

任何其他關於如何解決我的問題的建議將不勝感激(例如一個簡單的 python 腳本)。

我找到了一種使用python解決問題的方法:

import filecmp
import os.path

def find_unique_files(path_orig, path_duplicates, ommit_in_orig=[]):
   """
   Crawls all subfolders of path_duplicates and
   returns list of files (incl. paths) that occur
   in path_duplicates but no-where in path_orig,
   except for folders listed in ommit_in_orig. 
   Do not forget to add trailing '/' at the end of paths.
   
   Arguments:
   path_orig -- string
   path_duplicates -- string
   ommit_in_orig -- list of strings
   
   Returns:
   list of strings indicating paths to files.
   
   Example:
       find_unique_files('/home/user/project/', 
                         '/home/user/project/backups/',
                         ommit_in_orig=['/home/user/project/backups/',
                                        '/home/user/project/temp/'])
   """
   unique_files = []
   for folder, subfolders, files in os.walk(path_duplicates):
       print(folder, end='\r')

       for file in files:
           unique = 1
           filepath = os.path.join(folder,file)
           for folder1, subFolders1, files1 in os.walk(path_orig):
               # Check if folder1 is a subfolder of ommit_in_orig
               ommit = [s for s in ommit_in_orig if s.lower() in folder.lower()]
               if len(ommit) == 0:
                   if file in files1:
                       filepath1 = os.path.join(folder1, file)
                       if filecmp.cmp(filepath,filepath1):
                           # File is identical
                           unique = 0
           if unique == 1:
               unique_files.append(filepath)
   return unique_files
path_orig = 'orig/'
path_duplicates = 'backup/'
find_unique_files(path_orig, path_duplicates)

引用自:https://unix.stackexchange.com/questions/634636