如何检查多个文件夹并删除具有唯一文件名的任何文件?

2024-10-03 04:33:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个检查系统上用多个摄像头拍摄小部件的图像。如果检查失败,则不会保存图像。图像以小部件的序列号命名

所以我的文件夹结构可能看起来像

  • 照相机1
    • 1.tif
    • 2.tif
    • 4.tif
  • 照相机2
    • 2.tif
    • 3.tif
    • 4.tif
  • 照相机3
    • 1.tif
    • 2.tif
    • 3.tif
    • 4.tif

我希望能够删除所有三个文件夹中不匹配的图像。我不介意将解决方案运行两次,一次在camera1和camera2之间,然后再次使用camera2和Camera3

我希望只剩下以下文件夹结构

  • 照相机1
    • 2.tif
    • 4.tif
  • 照相机2
    • 2.tif
    • 4.tif
  • 照相机3
    • 2.tif
    • 4.tif

每个文件夹中约有12000个文件用于分析,可能有2%-3%的错误需要删除才能继续分析

我不介意需要支付、python、命令行等的预打包解决方案

多谢


Tags: 文件图像文件夹部件系统解决方案结构命名
3条回答

也许不是最快但非常简单的方法:

@echo off
rem // Change into root directory:
pushd "%~dp0." && (
    rem // Outer loop through target directories:
    for /D %%J in ("Camera?") do (
        rem // Create temporary file with matching contents of current directory:
        dir /B /A:-D-H-S "%%~J\*.tif" > "%TEMP%\%%~nxJ.log"
        rem // Inner loop through target directories:
        for /D %%I in ("Camera?") do (
            rem // Avoid comparing current directory with itself:
            if /I not "%%~I"=="%%~J" (
                rem /* List these files inside of the directory of the inner loop where no
                rem    respective files inside of the directory of the outer loop are found: */
                for /F "delims= eol=|" %%K in ('
                    dir /B /A:-D-H-S "%%~I\*.tif" ^| findstr /L /I /V /G:"%TEMP%\%%~nxJ.log"
                ') do (
                    rem // Actually delete current file:
                    ECHO del "%%~I\%%K"
                )
            )
        )
        rem // Delete temporary file:
        del "%TEMP%\%%~nxJ.log"
    )
    rem // Return from root directory:
    popd
)
exit /B

关键是在目标目录上有两个嵌套循环,以便相互比较,以及^{} command用于从一个目录中筛选出另一个目录中不存在的文件

测试正确的输出后,删除大写ECHO命令

正如评论中所建议的那样,下次你问一些关于SO的问题时,首先自己尝试一下,并询问任何问题——这样你会学到更多

下面是一个开始,正如建议的那样,下面的代码使用文件夹的内容创建3个集合,确定这三个集合的交集,然后从原始集合中删除该交集。结果准确地告诉您需要删除每个文件夹中的哪些文件:

from pathlib import Path


def find_unmatched(dirs):
    # list the (file) contents of the folders
    contents = {}
    for d in dirs:
        contents[d] = set(str(n.name) for n in Path(d).glob('*') if n.is_file())

    # decide what the folders have in common
    all_files = list(contents.values())
    common = all_files[0]
    for d_contents in all_files[1:]:
        common = common.intersection(d_contents)

    # create a dictionary that tells you what to remove
    return {d: files - common for d, files in contents.items()}


to_remove = find_unmatched(['photos/Camera1', 'photos/Camera2', 'photos/Camera3'])
print(to_remove)

结果(假设示例中的文件夹位于名为photos的文件夹中):

{'photos/Camera1': {'1.tif'}, 'photos/Camera2': {'3.tif'}, 'photos/Camera3': {'1.tif', '3.tif'}}

实际上,删除这些文件是一些你自己可能会明白的代码

如前所述,你应该尽自己的努力来解决问题,当你陷入困境时就寻求帮助。但是,我现在有一些空闲时间,所以我编写了一个完整的批处理解决方案:

@echo off
setlocal EnableDelayedExpansion

rem Process files in Camera1 folder and populate "F" array elements = 1
cd Camera1
for %%a in (*.tif) do set "F[%%~Na]=1"

rem Process files in Camera2 and *accumulate* files to "F" array
cd ..\Camera2
for %%a in (*.tif) do set /A "F[%%~Na]+=1"

rem Process files in Camera3 and accumulate files to "F" array
rem if counter == 3 then file is OK: remove "F" element
rem else: delete file
rem       if counter == 1: remove "F" element

cd ..\Camera3
for %%a in (*.tif) do (
   set /A "F[%%~Na]+=1"
   if !F[%%~Na]! equ 3 (
      set "F[%%~Na]="
   ) else (
      del %%a
      if !F[%%~Na]! equ 1 set "F[%%~Na]="
   )
)

rem Remove files of "F" array in both Camera1 and Camera2 folders, ignoring error messages
cd ..
(for /F "tokens=2 delims=[]" %%a in ('set F[') do (
   del Camera1\%%a.tif
   del Camera2\%%a.tif
)) 2>nul

请报告结果

相关问题 更多 >