比较两个目录,然后删除不匹配项 (Python)

发布于 2025-01-13 05:36:03 字数 1141 浏览 1 评论 0原文

你好 stackoverflow 社区!求助,已经伤透了如何实施。

例如,有文件夹:“D:\left”和“C:\right”。

它们包含的内容:文件、包含文件的目录、子目录、包含文件的子目录。大多数内容是相同的,但“C:\right”中可能有“额外”内容(与“D:\left”的内容不匹配)。

如何比较“С:\right”中的内容(“С:\right”中的内容)和“D:\left”中不存在的内容,然后(“С:\right”中的额外内容)将其删除,以便文件夹“D:” \left' 和 'C:\right' 变得相同(在我们的例子中,我们不考虑大小、时间等 - 纯粹通过它们内容的名称)。

尝试像这样删除多余的:

difs = list(set(os.listdir('C:\right')) - set(os.listdir('D:\left')))

但这还不够,因为它不会将效果传播到子目录。

也像这样:

from dirsync import sync
sync('D:\left', 'C:\right', 'diff')

但是,我只对输出的一小部分感兴趣,并且我根本不清楚如何准确地删除该输出。

删除 'C:\right' 中的所有内容以从 0 复制到 'D:\left' 到 'C:\right' 不是解决方案。

我很确定解决方案是固定的:

os.walk

但我只是无法将其正确排列:(

提前非常感谢您的帮助,我为我的愚蠢表示歉意。

为了清楚起见,我附上屏幕截图

入口: 入口 Entrance2

运行程序后期望的结果: 结果 结果2

Hello stackoverflow community! Help, already broke his head how to implement.

There are, for example, folders: 'D:\left' and 'C:\right'.

They contain the contents: files, directories with files, subdirectories, subdirectories with files. Most of the content is the same, but there may be 'extra' content in 'C:\right' (not matching the content of 'D:\left').

How can I compare the content (what is in) 'С:\right', what is not in 'D:\left' and after that (extra in 'С:\right') delete it so that the folders 'D:\left' and ' C:\right' became identical (in our case, we do not look at the size, time, etc. - purely by the names of their contents).

Tried like this to remove the excess:

difs = list(set(os.listdir('C:\right')) - set(os.listdir('D:\left')))

But this is not enough, because it does not propagate the effect to subdirectories.

Also like this:

from dirsync import sync
sync('D:\left', 'C:\right', 'diff')

But, there I am only interested in a small part of the output, and how exactly to put this output under deletion is simply not clear to me.

Delete everything from 'C:\right' to copy from 0 to 'D:\left' to 'C:\right' is not a solution.

I'm pretty sure the solution is fixated on:

os.walk

But I just can't line it up right :(

Many thanks in advance for any help and I apologize for the stupidity.

I'm attaching screenshots for clarity

Entrance:
Entrance
Entrance2

Desired result after running the program:
Result
Result2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乄_柒ぐ汐 2025-01-20 05:36:03

您可以使用 Path.rglob< /a>:

from pathlib import Path

pl = Path(path/to/left)
pr = Path(path/to/right)

difference = (set(map(lambda p: p.relative_to(pr), pr.rglob('*'))) -
              set(map(lambda p: p.relative_to(pl), pl.rglob('*'))))

这里是一个例子:

right
  file1
  file5
  dir1
    file2
    file6
  dir2
    file3
    file7
    subdir1
      file4
      file8
    subdir2
      file9
    subdir3

left
  file1
  dir1
    file2
  dir2
    file3
    subdir1
      file4
>>> difference
{PosixPath('dir1/file6'),
 PosixPath('file5'),
 PosixPath('dir2/subdir3'),
 PosixPath('dir2/subdir2'),
 PosixPath('dir2/subdir1/file8'),
 PosixPath('dir2/subdir2/file9'),
 PosixPath('dir2/file7')}

现在您只需删除difference中的所有文件和目录即可。

You can use Path.rglob:

from pathlib import Path

pl = Path(path/to/left)
pr = Path(path/to/right)

difference = (set(map(lambda p: p.relative_to(pr), pr.rglob('*'))) -
              set(map(lambda p: p.relative_to(pl), pl.rglob('*'))))

Here is an example:

right
  file1
  file5
  dir1
    file2
    file6
  dir2
    file3
    file7
    subdir1
      file4
      file8
    subdir2
      file9
    subdir3

left
  file1
  dir1
    file2
  dir2
    file3
    subdir1
      file4
>>> difference
{PosixPath('dir1/file6'),
 PosixPath('file5'),
 PosixPath('dir2/subdir3'),
 PosixPath('dir2/subdir2'),
 PosixPath('dir2/subdir1/file8'),
 PosixPath('dir2/subdir2/file9'),
 PosixPath('dir2/file7')}

Now you just need to delete all files and directories in difference.

一身软味 2025-01-20 05:36:03

非常感谢 Riccardo Bucco 的回复。我做到了,现在看起来像这样:

from pathlib import Path
import shutil
import os

pl = Path(left_way) # left_way = r'D:\left' = 'D:\\left' 
pr = Path(right_way) 
difference = (set(map(lambda p: p.relative_to(pr), pr.rglob('*'))) - set(
        map(lambda p: p.relative_to(pl), pl.rglob('*')))) # RB genius move

if len(difference) > 0:
    print('\nContent to be deleted:\n')
        for a in difference:
            a2 = Path(pr, a)
            print('   ', a2)
        while True:
            copyornot = input('\nDelete? (Y/n):\n')
            if copyornot == 'Y':
                break
            elif copyornot == 'n':
                print('...')
                continue
            else:
                print('(Y/n)')
        for a in difference:
            a2 = Path(pr, a)
            if os.path.isfile(a2):
                os.remove(a2)
            if os.path.isdir(a2):
                shutil.rmtree(a2)
        print('\nShift is over, go drink beer')

Thank Riccardo Bucco very much for his reply. I did it and now it looks like this:

from pathlib import Path
import shutil
import os

pl = Path(left_way) # left_way = r'D:\left' = 'D:\\left' 
pr = Path(right_way) 
difference = (set(map(lambda p: p.relative_to(pr), pr.rglob('*'))) - set(
        map(lambda p: p.relative_to(pl), pl.rglob('*')))) # RB genius move

if len(difference) > 0:
    print('\nContent to be deleted:\n')
        for a in difference:
            a2 = Path(pr, a)
            print('   ', a2)
        while True:
            copyornot = input('\nDelete? (Y/n):\n')
            if copyornot == 'Y':
                break
            elif copyornot == 'n':
                print('...')
                continue
            else:
                print('(Y/n)')
        for a in difference:
            a2 = Path(pr, a)
            if os.path.isfile(a2):
                os.remove(a2)
            if os.path.isdir(a2):
                shutil.rmtree(a2)
        print('\nShift is over, go drink beer')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文