【问题标题】:How to organize files in folders如何组织文件夹中的文件
【发布时间】:2023-01-05 17:38:19
【问题描述】:

我有这个脚本目前部分有​​效。第 1 步(工作):更准确地说,它将我在目录中找到的所有 .mp4 文件分组。我选择每个文件夹中 .mp4 文件的数量。 到目前为止一切都很好。

第 2 步(不工作):当我尝试移动与 mp4 文件一起创建的文件夹并将它们按 15 或我需要的数量分组时,我找不到最佳解决方案。

@echo off
setlocal enabledelayedexpansion
PushD %~dp0
set "filesInfolder=60"
set "foldersInfolders=15"
set "fcount=0"
set "fcounta=0"
set idx=0
set idxa=0

REM here all the .mp4 files will be grouped 60 in each folder

for /F "delims=" %%I in ('dir /a-d /o:n /b *.mp4') do (
    REM echo Processing %%I
    set /a idx=idx %% filesinfolder +1
    if !idx! equ 1 set /a fcount+=1
    md Videos-!fcount! 2>nul
    move "%%I" "Videos-!fcount!\"

  ) 
 
REM here I need the folders created together with the .mp4 files to be grouped by 15 in other folders.

for /D "delims=" %%A in (*.*) do  (
    REM echo Processing %%A
    set /Y idxa=idxa %% foldersinfolders +1
    if !idxa! equ 1 set /a fcounta+=1
    md Canal-!fcounta! 2>nul
    move "%%~fA" "Canal-!fcounta!\"

  
)
 

一切都在循环中发生,直到所有 .mp4 文件都完成

【问题讨论】:

  • 什么是Set /Y;)
  • @Gerhard 谢谢你的回答。我从tutorialspoint.com/batch_script/batch_script_moving_folders.htm那里获取了信息我尝试了各种选择,希望找到解决方案:(
  • 好的,set 没有这样的开关,您可以通过从cmd 运行set /? 来查看所有可用的开关。无论如何,for /D 不使用 delims= 只有 /F 可以。 for /D %%A in (*.*) do (也是如此,从set中删除/Y并替换为/a
  • I tried all kinds of options - 猜测命令的有效选项充其量是次优的。最好询问命令本身,它支持哪些开关,例如 set /?。我建议收藏(并经常访问)SS64
  • @Gerhard 最初它是 set /a,但我一直在修改代码,直到我写了一些愚蠢的东西,之后我才没有注意到它。已经谢谢你了!我离解决问题越来越近了。 :)

标签: batch-file cmd directory


【解决方案1】:

可以使用以下批处理文件通过将视频文件移动到动态创建的目录来组织批处理文件目录中的视频文件,只要没有 MP4 文件在文件名中包含感叹号即可。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0"
if not exist "*!*.mp4" goto MoveFiles
echo ERROR: Moving video files not possible because of file names with ! in name.
echo/
echo Please rename first the following files(s):
echo/
dir *!*.mp4 /A-D /B
echo/
pause
goto EndBatch

:MoveFiles
setlocal EnableDelayedExpansion
set "FilesInFolder=60"
set "FoldersInFolders=15"
set "FileCount=%FilesInFolder%"
set "CanalIndex=0"
set "VideosIndex=%FoldersInFolders%
for /F "eol=| delims=" %%I in ('dir *.mp4 /A-D /B /ON 2^>nul') do (
    if !FileCount! == %FilesInFolder% (
        set FileCount=0
        if !VideosIndex! == %FoldersInFolders% (
            set /A CanalIndex+=1
            set VideosIndex=1
        ) else set /A VideosIndex+=1
        set "TargetFolder=Canal-!CanalIndex!Videos-!VideosIndex!"
        md "!TargetFolder!" 2>nul
    )
    move /Y "%%I" "!TargetFolder!" >nul
    set /A FileCount+=1
)
endlocal

:EndBatch
popd
endlocal

环境变量TargetFolder有两个动态变化的数字CanalIndexVideosIndex可以进一步修改为想要的格式。

阅读有关 Using command redirection operators 的 Microsoft 文档,了解 2>nul 的解释。重定向运算符 > 必须使用脱字符 ^ 进行转义为了当 Windows 命令解释器在执行命令之前处理此命令行时,命令行将被解释为文字字符为了它使用在后台启动的单独命令进程执行嵌入式dir命令行。

请注意,由选项/ON引起的MP4文件按名称排序目录是严格的字母而不是自然的字母数字。执行的命令行为了通过在后台使用选项/c启动另一个cmd.exe,并且可以修改作为参数字符串附加的命令行以获取 MP4 文件名输出,然后以不同的顺序进行下一步处理。

的例子为了使用文件名file (1).mp4、... file (9).mp4file (10).mp4、... file (99).mp4file (100).mp4、... file (999).mp4file (1000).mp4、... file (9999).mp4:

for /F "eol=| delims=" %%I in ('dir *.mp4 /A-D /B /ON 2^>nul ^| %SystemRoot%System32indstr.exe /I /R "([0-9]).mp4$" ^& dir *.mp4 /A-D /B /ON 2^>nul ^| %SystemRoot%System32indstr.exe /I /R "([0-9][0-9]).mp4$" ^& dir *.mp4 /A-D /B /ON 2^>nul ^| %SystemRoot%System32indstr.exe /I /R "([0-9][0-9][0-9]).mp4$" ^& dir *.mp4 /A-D /B /ON 2^>nul ^| %SystemRoot%System32indstr.exe /I /R "([0-9][0-9][0-9][0-9]).mp4$"') do (

请注意[0-9] 也匹配字符¹²³ 在这里应该没有问题。

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

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • move /?
  • pause /?
  • popd /?
  • pushd /?
  • set /?
  • setlocal /?

扩展版处理第一个指定的多个目录下的MP4文件为了循环而不是批处理文件目录:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FilesInFolder=60"
set "FoldersInFolders=15"
for %%# in ("%USERPROFILE%Videos" "D:Videos" "F:TempVideos" "\MyNASVideos") do (
    pushd %%# 2>nul
    if not errorlevel 1 (
        if not exist "*!*.mp4" (
            setlocal EnableDelayedExpansion
            set "FileCount=%FilesInFolder%"
            set "CanalIndex=0"
            set "VideosIndex=%FoldersInFolders%
            for /F "eol=| delims=" %%I in ('dir *.mp4 /A-D /B /ON 2^>nul') do (
                if !FileCount! == %FilesInFolder% (
                    set FileCount=0
                    if !VideosIndex! == %FoldersInFolders% (
                        set /A CanalIndex+=1
                        set VideosIndex=1
                    ) else set /A VideosIndex+=1
                    set "TargetFolder=Canal-!CanalIndex!Videos-!VideosIndex!"
                    md "!TargetFolder!" 2>nul
                )
                move /Y "%%I" "!TargetFolder!" >nul
                set /A FileCount+=1
            )
            endlocal
        ) else (
            echo/
            echo ERROR: Moving video files not possible because of file names with ! in name.
            echo/
            echo Please rename first the following files(s^) in: %%#
            echo/
            dir *!*.mp4 /A-D /B
            echo/
            pause
        )
        popd
    ) else (
        echo/
        echo ERROR: Failed to change to directory: %%#
        echo/
        pause
    )
)
endlocal

【讨论】:

  • 我怎样才能在多个外部目录中执行完全相同的脚本实用程序?我需要它用于 4 个单独的目录,并避免为每个目录复制此脚本。所有的设置都是相同的,只是可以添加几个彼此不相关的目录。也就是说,它们不是子目录。它们是完全独立的,在不同的地方。 set "videodir1= set "videodir2= set "videodir3= set "videodir4= 谢谢
  • @IonutBejinariu 请参阅扩展答案。如果第二个批处理文件适用于您选择的目录,请删除您的评论,不要写新评论。那我也把这条评论删了。
【解决方案2】:

我设法使它工作。我以这种形式附上代码版本,我还将提出一个带有单个 for 循环的版本。

如果有人想优化这个解决方案,它是免费的,我真的很鼓励。非常感谢你!

更新:我做了一个优化版本。感谢@Mofi

@echo off
setlocal EnableExtensions EnableDelayedExpansion
pushd "%~dp0"
set "filesInfolder=60"
set "foldersInfolders=15"
set "fcount=0"
set "fcounta=0"
set idx=0
set idxa=0

 
for /F "delims=" %%I in ('dir /a-d /o:n /b *.mp4') do (
    REM echo Processing %%I
    set /a idx=idx %% filesinfolder +1
    if !idx! == 1 set /a fcount+=1
    md Videos-!fcount! 2>nul
    move "%%I" "Videos-!fcount!"

  ) 
 
for /D %%A in (*.*) do  (
    REM echo Processing %%A
    set /a idxa=idxa %% foldersinfolders +1
    if !idxa! == 1 set /a fcounta+=1
    md Canal-!fcounta! 2>nul
    move "%%~fA" "Canal-!fcounta!"

  
)
endlocal
 

后期编辑:

现在目录按名称字母顺序排列。 Videos-1, Videos-10, Videos-11, ... Video-19 我需要它们以自然的字母数字顺序排列

我找到了一个临时解决方案,可以连续重命名我所有的内部文件夹,但最后我会在文件夹结构中解释如何对我来说更好。

我刚刚修改:

md Videos-!fcount! 2>nul
move "%%I" "Videos-!fcount!" 

并做到了

md Videos-!fcount!-123 2>nul
move "%%I" "Videos-!fcount!-123" 

我有文件MP4 文件文件夹

───MP4-files Folder
│   ├───file.mp4 - (1)
│   ├───file.mp4 - (10)
│   ├───file.mp4 - (11)
│   ├───file.mp4 - (2)
│   ├───file.mp4 - (3)
│   ├───file.mp4 - (4)
│   ├───file.mp4 - (5)
│   ├───file.mp4 - (6)
│   ├───file.mp4 - (7)
│   ├───file.mp4 - (8)
│   └───file.mp4 - (9)

在这里我运行上面的批处理文件(有那个小修改-123 ) 并且所有 .mp4 文件首先在 Videos-1、Videos-2 ... Videos- xx 中移动,具体取决于我在文件夹中有多少 .mp4 文件。 每个视频文件夹中都有 mp4 文件(取决于我在脚本中写了多少)set "filesInfolder=60" 现在是,但可以不同。

之后,文件夹 Videos-1 .. Videos-xx 按顺序分组在名称为“Canal-1 .. Canal-10 .. Canal-x”的其他文件夹中。文件夹的数量取决于视频文件夹的数量。我组多少人在这里set "foldersInfolders=15"可以是15或其他数字。

我明白了:

─MP4-files Folder
│       ├───Canal-1 ->  (set "foldersInfolders=15")
│       │   ├───Videos-1-123  (inside are the .mp4 files) -> set "filesInfolder=60"
│       │   ├───Videos-10-123
│       │   ├───Videos-100-123
│       │   ├───Videos-101-123
│       │   ├───Videos-102-123
│       │   ├───Videos-103-123
│       │   ├───Videos-104-123
│       │   ├───Videos-105-123
│       │   ├───Videos-106-123
│       │   ├───Videos-107-123
│       │   ├───Videos-108-123
│       │   ├───Videos-109-123
│       │   ├───Videos-11-123
│       │   ├───Videos-110-123
│       │   └───Videos-111-123
│       ├───Canal-2
│       │   ├───Videos-12-123
│       │   ├───Videos-13-123
│       │   ├───Videos-14-123
│       │   ├───Videos-15-123
│       │   ├───Videos-16-123
│       │   ├───Videos-17-123
│       │   ├───Videos-18-123
│       │   ├───Videos-19-123
│       │   ├───Videos-2-123
│       │   ├───Videos-20-123
│       │   ├───Videos-21-123
│       │   ├───Videos-22-123
│       │   ├───Videos-23-123
│       │   ├───Videos-24-123
│       │   └───Videos-25-123
│       ├───Canal-3
│       │   ├───Videos-26-123
│       │   ├───Videos-27-123
│       │   ├───Videos-28-123
│       │   ├───Videos-29-123
│       │   ├───Videos-3-123
│       │   ├───Videos-30-123
│       │   ├───Videos-31-123
│       │   ├───Videos-32-123
│       │   ├───Videos-33-123
│       │   ├───Videos-34-123
│       │   ├───Videos-35-123
│       │   ├───Videos-36-123
│       │   ├───Videos-37-123
│       │   ├───Videos-38-123
│       │   └───Videos-39-123
 

然后我运行以下批处理文件:

@Echo off
  
set Cnt=0
for /f "delims=" %%A in (
  'dir /B /S /AD Videos-* ^| findstr /iV "^Videos-[0-9][0-9]*$" '
) Do Call :RenInc "%%A"
PopD    
Goto :Eof

:RenInc
Set /A Cnt+=1
if Exist "Videos-%Cnt%" goto :RenInc
Ren "%~1" "Videos-%Cnt%"

我得到以下文件夹结构:

──Video-15-sec
│       ├───Canal-1
│       │   ├───Videos-1
│       │   ├───Videos-2
│       │   ├───Videos-3
│       │   ├───Videos-4
│       │   ├───Videos-5
│       │   ├───Videos-6
│       │   ├───Videos-7
│       │   ├───Videos-8
│       │   ├───Videos-9
│       │   ├───Videos-10
│       │   ├───Videos-11
│       │   ├───Videos-12
│       │   ├───Videos-13
│       │   ├───Videos-14
│       │   └───Videos-15
│       ├───Canal-2
│       │   ├───Videos-16
│       │   ├───Videos-17
│       │   ├───Videos-18
│       │   ├───Videos-19
│       │   ├───Videos-20
│       │   ├───Videos-21
│       │   ├───Videos-22
│       │   ├───Videos-23
│       │   ├───Videos-24
│       │   ├───Videos-25
│       │   ├───Videos-26
│       │   ├───Videos-27
│       │   ├───Videos-28
│       │   ├───Videos-29
│       │   └───Videos-30
│       ├───Canal-3
│       │   ├───Videos-31
│       │   ├───Videos-32
│       │   ├───Videos-33
│       │   ├───Videos-34
│       │   ├───Videos-35
│       │   ├───Videos-36
│       │   ├───Videos-37
│       │   ├───Videos-38
│       │   ├───Videos-39
│       │   ├───Videos-40
│       │   ├───Videos-41
│       │   ├───Videos-42
│       │   ├───Videos-43
│       │   ├───Videos-44
│       │   └───Videos-45
│       ├───Canal-4

这很好,但如果我在运行 1 次本答案中附加的第一个批处理文件后可以获得以下文件夹结构,对我来说更好。

──Video-15-sec
│       ├───Canal-1
│       │   ├───Videos-1
│       │   ├───Videos-2
│       │   ├───Videos-3
│       │   ├───Videos-4
│       │   ├───Videos-5
│       │   ├───Videos-6
│       │   ├───Videos-7
│       │   ├───Videos-8
│       │   ├───Videos-9
│       │   ├───Videos-10
│       │   ├───Videos-11
│       │   ├───Videos-12
│       │   ├───Videos-13
│       │   ├───Videos-14
│       │   └───Videos-15
│       ├───Canal-2
│       │   ├───Videos-1
│       │   ├───Videos-2
│       │   ├───Videos-3
│       │   ├───Videos-4
│       │   ├───Videos-5
│       │   ├───Videos-6
│       │   ├───Videos-7
│       │   ├───Videos-8
│       │   ├───Videos-9
│       │   ├───Videos-10
│       │   ├───Videos-11
│       │   ├───Videos-12
│       │   ├───Videos-13
│       │   ├───Videos-14
│       │   └───Videos-15
│       ├───Canal-3
│       │   ├───Videos-1
│       │   ├───Videos-2
│       │   ├───Videos-3
│       │   ├───Videos-4
│       │   ├───Videos-5
│       │   ├───Videos-6
│       │   ├───Videos-7
│       │   ├───Videos-8
│       │   ├───Videos-9
│       │   ├───Videos-10
│       │   ├───Videos-11
│       │   ├───Videos-12
│       │   ├───Videos-13
│       │   ├───Videos-14
│       │   └───Videos-15
│       ├───Canal-4

十分感谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    相关资源
    最近更新 更多