如何将数千个图像文件移动到每个包含 400 个图像文件的子文件夹中?

Posted

技术标签:

【中文标题】如何将数千个图像文件移动到每个包含 400 个图像文件的子文件夹中?【英文标题】:How to move thousands of image files into subfolders each with 400 image files? 【发布时间】:2021-11-24 07:30:53 【问题描述】:

我有 2000 张图像,我想将它们移动到不同的文件夹中。每个文件夹应包含 400 张图像,并且每个文件夹位于不同的路径中。

\Desktop\images 包含:

0001.jpeg
0002.jpeg
...
2000.jpeg

文件应该被移动到文件夹中:

\Desktop\Project\Folder1\images:

0001.jpeg
0002.jpeg
...
0400.jpeg

\Desktop\Project\Folder2\images

0401.jpeg
0402.jpeg
...
0800.jpeg

\Desktop\Project\Folder3\images:

1801.jpeg
1802.jpeg
...
1200.jpeg

\Desktop\Project\Folder4\images:

1201.jpeg
1202.jpeg
...
1600.jpeg

\Desktop\Project\Folder5\images:

1601.jpeg
1602.jpeg
...
2000.jpeg

Graphical display of the folders

【问题讨论】:

mkdir和***.com/questions/138497/…和move 【参考方案1】:

当您使用的是配备powershell 的操作系统时,这里有一个替代方案:

DistributeFiles.ps1

$DesktopPath = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::Desktop)

$SourceDir = $DesktopPath + "\images"
$FileMask = "*.jpeg"
$DestDir = $DesktopPath + "\Project"
$FilesPerDir = 400
$DestStartNum = 1

$i = 0
Get-ChildItem -Path $SourceDir -Filter $FileMask -Name | Sort-Object | ForEach-Object 
   New-Item -Path ($DestDir + "\Folder" + $DestStartNum) -Type Directory -Force > $Null
   Move-Item ($SourceDir + "\" + $_) ($DestDir + "\Folder" + $DestStartNum)
   $i++
   If ($i -Eq $FilesPerDir) 
      $DestStartNum++
      $i = 0
   

为了使用 cmd 标记保持主题,您可以从命令提示符窗口运行该脚本,如下所示:

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy RemoteSigned -File "L:\ocation\Of\DistributeFiles.ps1"

【讨论】:

【参考方案2】:

另一种方法是使用已在受支持的 Windows 系统上的 PowerShell。此cmd .bat 文件脚本运行一个 PowerShell 脚本,该脚本将使用 .jpeg 文件名的前四 (4) 位数字来确定应将其移动到哪个目录。不会移动不以四 (4) 位开头的文件。

将 .bat 和 .ps1 文件放在同一目录中。当您对将创建正确的目录并将文件移动到正确的目录感到满意时,请从 mkdirMove-Item 命令中删除 -WhatIf

=== DistributeFiles.bat

@powershell -NoLogo -NoProfile -File "%~dp0%~n0.ps1"

=== DistributeFiles.ps1

$ProjectPath = Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop\Project';
$NFilesPerDirectory = 400;
Get-ChildItem -File -Path (Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop\images') -Filter '*.jpeg' |
    ForEach-Object 
        # Check to see if the filename starts with four (4) digits.;
        if ($_.BaseName -match '^(\d4).*') 
            $FolderNumber = [math]::Floor([int]$Matches[1] / $NFilesPerDirectory);
            $FolderName = 'Folder' + $FolderNumber.ToString();
            $FolderPath = Join-Path -Path $ProjectPath -ChildPath $FolderName;
            # If the destination directory does not exist, create it.;
            if (-not (Test-Path -Path $FolderPath))  mkdir $FolderPath -WhatIf | Out-Null 
            # Move the file to the destination directory.;
            Move-Item -Path $_.FullName -Destination $FolderPath -WhatIf
        
    

如果由于某种原因您无法使用 .ps1 脚本文件,则可以将其编码到 .bat 文件脚本中。

powershell -NoLogo -NoProfile -Command ^
    $ProjectPath = Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop\Project'; ^
    $NFilesPerDirectory = 400; ^
    Get-ChildItem -File -Path (Join-Path -Path $Env:USERPROFILE -ChildPath 'Desktop\images') -Filter '*.jpeg' ^| ^
        ForEach-Object  ^
            ^<# Check to see if the filename starts with four (4) digits.#^> ^
            if ($_.BaseName -match '^^(\d4).*')  ^
                $FolderNumber = [math]::Floor([int]$Matches[1] / $NFilesPerDirectory); ^
                $FolderName = 'Folder' + $FolderNumber.ToString(); ^
                $FolderPath = Join-Path -Path $ProjectPath -ChildPath $FolderName; ^
                ^<# If the destination directory does not exist, create it.#^> ^
                if (-not (Test-Path -Path $FolderPath))  mkdir $FolderPath -WhatIf ^| Out-Null ; ^
                ^<# Move the file to the destination directory.#^> ^
                Move-Item -Path $_.FullName -Destination $FolderPath -WhatIf; ^
            ; ^
        ;

【讨论】:

【参考方案3】:

这是这个文件移动任务的注释批处理文件,其中包含一些额外内容以使其变得有趣(对我而言):

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%UserProfile%\Desktop\images"
if not exist "%SourceFolder%\*.jpeg" goto :EOF

set "DestinationPath=%UserProfile%\Desktop\Project"
set "DestinationName=Folder"
set "FolderNameLength=6"
set "MaxFileCount=400"

setlocal EnableDelayedExpansion
set "FolderNumber=0"
set "FileCount=%MaxFileCount%"
set "DestinationFolder=!DestinationPath!\!DestinationName!"

rem Search for all non-hidden subfolders with a name starting with the
rem destination folder name and having a number append and determine
rem the greatest folder number in all existing folder names. Folder
rem names with one or more leading zeros are not supported by this code.

for /F "delims=" %%I in ('dir "!DestinationFolder!*" /AD-H-L /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /I /R "^folder[0123456789][0123456789]*$"') do (
    set "FolderName=%%I"
    if !FolderName:~%FolderNameLength%! GTR !FolderNumber! set "FolderNumber=!FolderName:~%FolderNameLength%!"
)

rem Determine the number of *.jpeg files in the images folder in the folder
rem with greatest folder number if there is an existing images folder at all.

if exist "!DestinationFolder!!FolderNumber!\images\" (
    set "FileCount=0"
    for /F "eol=| delims=" %%I in ('dir "!DestinationFolder!!FolderNumber!\images\*.jpeg" /A-D /B 2^>nul') do set /A FileCount+=1
)

rem Get a list of JPEG files in source folder loaded into memory of the
rem Windows command processor ordered by name and move all these files
rem with making sure that no images folder has more than the number of
rem JPEG files as defined above. The code below is not capable moving
rem files with one or more exclamation marks because of always enabled
rem delayed expansion.

rem Note: The command DIR orders the file names strictly alphabetically
rem       and not alphanumerical as done by Windows File Explorer. So
rem       the JPEG file names should have all the same number of digits.

for /F "eol=| delims=" %%I in ('dir "!SourceFolder!\*.jpeg" /A-D /B /ON 2^>nul') do (
    set /A FileCount+=1
    if !FileCount! GTR %MaxFileCount% (
        set "FileCount=1"
        set /A FolderNumber+=1
        md "!DestinationFolder!!FolderNumber!\images"
    )
    echo Moving file "%%I" to "!DestinationFolder!!FolderNumber!\images\"
    move "!SourceFolder!\%%I" "!DestinationFolder!!FolderNumber!\images\"
    if errorlevel 1 set /A FileCount-=1
)
endlocal
endlocal

此批处理文件适用于根本不存在的目标文件夹以及一些已存在的目标文件夹,在这种情况下,将找出目标文件夹中数量最多的 JPEG 文件的数量,以确定要另外移动多少 JPEG 文件到FolderX 编号最大的images 文件夹。

请注意,SourceFolderDestinationPathDestinationNameFolderNameLengthMaxFileCount 必须适应当地要求。

要了解所使用的命令及其工作原理,请打开command prompt 窗口,在那里执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

dir /? echo /? endlocal /? findstr /? goto /? if /? md /? move /? rem /? set /? setlocal /?

阅读有关Using command redirection operators 的Microsoft 文档,了解2&gt;nul| 的解释。重定向运算符 &gt;| 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令之前处理这些命令行时被解释为文字字符 FOR 执行嵌入的dir 命令行,不带或带findstr 在后台启动的单独命令进程中,%ComSpec% /c' 中的命令行作为附加参数附加。

【讨论】:

谢谢它的工作:) 对于其他读者:这个答案被否决是为了报复删除投票。代码绝对没问题,解释准确。

以上是关于如何将数千个图像文件移动到每个包含 400 个图像文件的子文件夹中?的主要内容,如果未能解决你的问题,请参考以下文章

如何限制将捏缩放图像移动到图像边框?

如何在 React 中动态导入图像?

输出图像到文本文件的差异

在 xcode for iOS 应用程序中存储数千个文件(在包内)

如何快速从文件夹中获取随机图像?

如何在Keras中使用中级微调?