Board logo

标题: [文件操作] 求助批处理修改文件名、识别文件夹名字后移动文件、分割文件 [打印本页]

作者: 304802301    时间: 2024-10-14 16:08     标题: 求助批处理修改文件名、识别文件夹名字后移动文件、分割文件

各位大哥,我这里有3个批处理的需求,求助论坛里的大神,感谢!!!

一、批量修改文件名字、文件夹名字
1、我这边会提供一个【清单.txt】文本文件,根据清单里的对应关系,批量修改文件名字、文件夹名字。
2、清单里会罗列对应关系
>比如第一行A+B,指的是去找文件名字或者文件夹名字是【A】的,然后修改成【B】
>比如第二行AA+BB,指的是去找文件名字或者文件夹名字是【AA】的,然后修改成【BB】
3、注意下必须是完全匹配的才去修改
4、如果是修改文件名字的,文件的格式不要变
5、允许我指定清单的路径和需要处理的文件夹路径,需要遍历指定文件夹下面所有的文件夹及子文件夹



二、识别到特定的文件夹名字后把下面的文件移动到本层路径下
1、比如有个路径 【A/b/2024年/file/1.pdf】,识别到file这个文件夹之后,把下面的1.pdf移动到和file同一层级的文件夹,移动后的路径效果是【A/b/2024年/1.pdf】
2、上面例子是要识别文件夹名字是file,允许我自己后续修改
3、识别的文件夹名字要求全部吻合才处理,比如我要求识别file文件夹名字,搜索到file1、1file、fil5e等都不算匹配到
4、允许我指定需要处理的文件夹路径,需要遍历指定文件夹下面所有的文件夹及子文件夹


三、文件按随机大小分割
1、比如有一个文件名字是【1.db】,大小为303M,需要按照我指定的容量范围(比如我指定范围是40M~50M),把文件分割,分割后每一个文件的大小在40M~50M之间随机,不固定。每个文件名字是原名字后面加上-000001,这样。
2、按上面的例子,分割后的效果:
>1-000001.db,大小比如45M
>1-000002.db,大小比如43M
>1-000003.db,大小比如46M
>1-000004.db,大小比如43M
>1-000005.db,大小比如49M
>1-000006.db,大小比如42M
>1-000007.db,大小比如35M
3、允许我调整容量指定范围,单位为M
4、允许我指定需要处理的文件夹路径,需要遍历指定文件夹下面所有的文件夹及子文件夹
5、另外需要合并的代码(可以分开2个bat,1个专用分割,1个专用合并),按上述分割的规则来合并成1个原始文件,合并也可以指定路径,子文件夹下面都要遍历,识别到相同的文件名后,按000001,000002的规则去合并。
6、有些是很大的文件(500G),代码层面可以考虑增加一个临时文件之类的过渡下。
作者: 77七    时间: 2024-10-14 20:43

Q1
  1. @echo off
  2. rem 清单和批处理全部保存为ansi编码
  3. set list=d:\清单.txt
  4. set dirpath=d:\test
  5. cd /d "%dirpath%"
  6. for /f "delims=" %%i in ('dir /b /s ^| sort /r') do (
  7. for /f "tokens=1-2 delims=+" %%a in ('find /i "%%~ni" ^< "%list%"') do (
  8. if /i "%%~ni" equ "%%a" (
  9. if exist "%%i\" (
  10. ren "%%i" "%%b"
  11. ) else (
  12. ren "%%i" "%%b%%~xi"
  13. )
  14. )
  15. )
  16. )
  17. pause
复制代码

作者: 77七    时间: 2024-10-14 21:08

Q2
  1. @echo off
  2. rem 批处理保存为ansi编码
  3. set folder=file
  4. set dirpath=d:\test
  5. cd /d "%dirpath%"
  6. for /f "delims=" %%i in ('dir /b /s /ad "%folder%"') do (
  7. move "%%i\*" "%%i\..\"
  8. )
  9. pause
复制代码

作者: czjt1234    时间: 2024-10-15 09:15

Q3 拆分文件
  1. rem 另存为 ANSI 编码 bat
  2. ' & cls & cscript.exe /nologo /e:vbscript "%~f0" %* & pause & exit /b
  3. Option Explicit
  4. Dim oFSO, oWshShell, oStream1, oStream2, s, p, L, U, f
  5. p = "d:\1.db"    '路径
  6. L = 40           '最小
  7. U = 50           '最大
  8. Set oFSO = CreateObject("Scripting.FileSystemObject")
  9. Set oWshShell = CreateObject("WScript.Shell")
  10. Set oStream1 = CreateObject("ADODB.Stream")
  11. oStream1.Type = 1    'adTypeBinary
  12. oStream1.Mode = 3    'adModeReadWrite
  13. Set oStream2 = CreateObject("ADODB.Stream")
  14. oStream2.Type = 1    'adTypeBinary
  15. oStream2.Mode = 3    'adModeReadWrite
  16. p = oFSO.GetAbsolutePathName(p)
  17. s = ""
  18. Call EnumFiles(p)
  19. For Each f In Split(Left(s, Len(s) - 2), vbCrLf)
  20.     Call t(f)
  21. Next
  22. wsh.Echo "ok"
  23. Sub t(ByVal f)
  24.     Dim i, size, n, t
  25.     wsh.Echo f
  26.     oWshShell.CurrentDirectory = oFSO.GetParentFolderName(f)
  27.     oStream1.Open()
  28.     oStream1.LoadFromFile f
  29.     size = oStream1.Size
  30.     If size <= L * 1024 * 1024 Then
  31.         wsh.Echo "无需分解" & vbCrLf
  32.         oStream1.Close()
  33.         Exit Sub
  34.     End If
  35.     n = 0
  36.     Do
  37.         n = n + 1
  38.         t = Right("000000" & n, 6)
  39.         t = oFSO.GetBaseName(f) & "-" & t & "." & oFSO.GetExtensionName(f)
  40.         Randomize
  41.         i = Int((U - L + 1) * Rnd() + L)
  42.         oStream2.Open()
  43.         oStream1.CopyTo oStream2, i * 1024 * 1024
  44.         oStream2.SaveToFile t, 2    'adSaveCreateOverWrite
  45.         i = Int(oStream2.Size / 1024 / 1024)
  46.         oStream2.Close()
  47.         wsh.Echo i & "M →" & vbTab & t
  48.         If oStream1.EOS Then
  49.             oStream1.Close()
  50.             wsh.Echo
  51.             Exit Sub
  52.         End If
  53.     Loop
  54. End Sub
  55. Sub EnumFiles(ByVal folderPath)
  56.     Dim oFile, oFolder      'oFSO, s 是全局变量
  57.     On Error Resume Next    '忽略无权限读取的文件夹和文件
  58.     For Each oFile In oFSO.GetFolder(folderPath).Files
  59.         s = s & oFile.Path & vbCrLf
  60.     Next
  61.     For Each oFolder In oFSO.GetFolder(folderPath).SubFolders
  62.         Call EnumFiles(oFolder.Path)
  63.     Next
  64. End Sub
复制代码

作者: qixiaobin0715    时间: 2024-10-15 09:34

本帖最后由 qixiaobin0715 于 2024-10-15 09:42 编辑

Q1
感觉楼主的这种修改文件名的方法,要想提高效率不是太容易。文件和文件夹分开重命名可能要好些,清单名称使用英文,可以尽量避免代码中出现中文,这样不容易出问题,比如list.txt:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "tokens=1-2 delims=+" %%i in (list.txt) do set "_%%i=%%j"
  4. for /f "delims=" %%i in ('dir /s /b /ad^|sort /r') do if defined _%%~nxi ren "%%i" "!_%%~nxi!"
  5. for /f "delims=" %%i in ('dir /s /b /a-d') do if defined _%%~ni ren "%%i" "!_%%~ni!.%%~xi"
  6. pause
复制代码

作者: czjt1234    时间: 2024-10-15 09:40

本帖最后由 czjt1234 于 2024-10-15 10:59 编辑

回复 4# czjt1234


不行,ADODB.Stream只能处理小于2G的文件

楼主的文件太大了,要第三方软件来处理
  1. "C:\Program Files\7-Zip\7z.exe" a -tZIP -mx0 "D:\1.zip" "D:\1.db" -v50M
复制代码
试了可以分卷压缩5G的文件
但是每个文件的大小都是一样的50M
作者: 304802301    时间: 2024-10-15 16:41

回复 2# 77七


    感谢大佬,Q1和Q2可以用,Q3能不能帮忙看下,感谢感谢
作者: 304802301    时间: 2024-10-15 16:43

回复 6# czjt1234


    感谢大佬,因为是文件要上传lanzouyun,分卷压缩的容量一样会被检测到不允许上传,所以才要随机容量大小的
作者: 304802301    时间: 2024-10-15 16:43

回复 5# qixiaobin0715


    感谢大佬!
作者: Five66    时间: 2024-10-15 17:56

啊 ,500G ,这么大的?
作者: flashercs    时间: 2024-10-15 18:01

本帖最后由 flashercs 于 2024-11-3 21:53 编辑

先测试,后投产,防止丢文件.我觉得分割后应该删除源文件的,否则500G变成了1TB,太占用磁盘.但 删除文件很危险.
Q1
  1. @echo off
  2. set "list=.\清单.txt"
  3. set "dir0=C:\D\Test\ps1\要处理的文件夹"
  4. for /f "usebackq tokens=1* delims=+" %%A in ("%list%") do set "?%%~A=%%~B"
  5. for /f "delims=" %%A in ('dir /a-d-h /b /s "%dir0%"') do (
  6.   if defined ?%%~nA (
  7.     setlocal enabledelayedexpansion
  8.     for %%B in ("!?%%~nA!") do (
  9.       endlocal
  10.       ren "%%~fA" "%%~B%%~xA"
  11.     )
  12.   )
  13. )
  14. for /f "delims=" %%A in ('dir /ad-h /b /s "%dir0%"^|sort /r') do (
  15.   if defined ?%%~nxA (
  16.     setlocal enabledelayedexpansion
  17.     for %%B in ("!?%%~nxA!") do (
  18.       endlocal
  19.       ren "%%~fA" "%%~B"
  20.     )
  21.   )
  22. )
  23. pause
复制代码
Q2
  1. @echo off
  2. set "file=文件夹名"
  3. set "dir0=C:\D\Test\ps1\要处理的文件夹"
  4. for /f "delims=" %%A in ('dir /ad-h /b /s "%dir0%"^|sort /r') do (
  5.   if /i "%%~nxA"=="%file%" (
  6.     move "%%~fA\*" "%%~dpA"
  7.   )
  8. )
  9. pause
复制代码
Q3 分割
  1. <#*,:
  2. @echo off
  3. cd /d "%~dp0"
  4. set "batchfile=%~f0"
  5. Powershell -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"
  6. pause
  7. exit /b
  8. #>
  9. $srcDir = "." # 要处理的文件夹路径 - 文件夹
  10. $filePattern = "*.db" # 要分割的文件类型
  11. $fragSizeRange = "40-50" # 文件分割容量范围,单位:MB
  12. $dstdir = ".\拆分后的目标路径" # 指定拆分后的文件存放路径
  13. $format = '{0}+{1:000000}{2}' # 拆分后的文件名格式
  14. $didst = [IO.Directory]::CreateDirectory($dstdir)
  15. $dirPath = $didst.FullName
  16. $buff = New-Object 'byte[]' -ArgumentList 64kb
  17. function Get-RandomSize {
  18.   [double]$lo, [double]$hi = $fragSizeRange -split '-'
  19.   $lo = $lo * 1mb
  20.   $hi = $hi * 1mb
  21.   if ($lo -eq $hi) {
  22.     $m = $lo
  23.   } elseif ($lo -gt $hi) {
  24.     $m = Get-Random -Minimum $hi -Maximum $lo
  25.   } else {
  26.     $m = Get-Random -Minimum $lo -Maximum $hi
  27.   }
  28.   $m
  29. }
  30. (Get-ChildItem -Path ("$srcDir\*" -replace '[\[\]]', '`$&') -Filter $filePattern -Recurse | Where-Object { $_ -is [IO.FileInfo] -and $_.FullName -ne $env:batchfile }) | ForEach-Object {
  31.   try {
  32.     $_.FullName
  33.     # $dirPath = [IO.Path]::GetDirectoryName($_.FullName)
  34.     $ctr = 1
  35.     $fragSize = Get-RandomSize
  36.     $fragName = $format -f $_.BaseName, $ctr, $_.Extension
  37.     $fragPath = [IO.Path]::Combine($dirPath, $fragName)
  38.     if ($_.Length -le $fragSize) {
  39.       $_.MoveTo($fragPath)
  40.       return
  41.     }
  42.     $stream1 = New-Object System.IO.FileStream -ArgumentList ($_.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::Read, 64kb)
  43.     $stream2 = New-Object System.IO.FileStream -ArgumentList ($fragPath, [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::None, 64kb)
  44.     $totalSize = 0
  45.     while (($readCount = $stream1.Read($buff, 0, $buff.Length)) -gt 0) {
  46.       $stream2.Write($buff, 0, $readCount)
  47.       $totalSize += $readCount
  48.       if ($totalSize -ge $fragSize) {
  49.         $stream2.Close()
  50.         if ($stream1.Position -ge $stream1.Length) {
  51.           break
  52.         }
  53.         $totalSize = 0
  54.         ++$ctr
  55.         $fragSize = Get-RandomSize
  56.         $fragName = $format -f $_.BaseName, $ctr, $_.Extension
  57.         $fragPath = [IO.Path]::Combine($dirPath, $fragName)
  58.         $stream2 = New-Object System.IO.FileStream -ArgumentList ($fragPath, [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::None, 64kb)
  59.       }
  60.     }
  61.     $stream1.Close()
  62.     $stream2.Close()
  63.     # 删除原文件
  64.     # $_ | Remove-Item
  65.   } finally {
  66.     if ($stream1) { $stream1.Close(); $stream1 = $null; }
  67.     if ($stream2) { $stream2.Close(); $stream2 = $null; }
  68.   }
  69.   trap {}
  70. }
复制代码
Q3 合并
  1. @echo off
  2. @REM 要处理的文件夹
  3. set "dir0=."
  4. @REM 要合并的文件类型
  5. set "pattern=*+*.db"
  6. @REM 指定合并后的文件存放路径
  7. set "dir1=.\合并后的路径"
  8. md "%dir1%" 2>nul
  9. for /f "delims=" %%A in ('dir /a-h-d /b /s "%dir0%\%pattern%"') do (
  10.   for /f "delims=+" %%B in ("%%~nA") do (
  11.     if not defined ?%%~dpA%%~B (
  12.       set "?%%~dpA%%~B=1"
  13.       copy /b "%%~dpA%%~B+*%%~xA" "%dir1%\%%~B%%~xA"
  14.     )
  15.   )
  16. )
  17. pause
复制代码

作者: 77七    时间: 2024-10-15 20:02

winrar 可以指定分卷大小
  1. 创建 卷 及大小 = <n> *1000
  2. 默认此参数使用 <n> 作为一千个 (1000) 字节 (非 1024 x 字节)。您也可以输入符号“k”来表示千字节的大小,或者符号“b”表示字节,在百万字节为 -‘m’,一百万个字节为 -‘M’ G 字节 - ‘g’十亿个字节 -‘G’。如果省略了大小,将会使用自动检测。
  3. 它允许使用十进位小数作为十进制的标记。例如,v1.5g 参数表示 1.5 GB。
  4. 您可以指定几个 -v 参数来为不同的卷设置不同的大小。例如 :
  5. WinRAR a -v100k -v200k -v300k arcname
复制代码



使用须把rar.exe添加到环境变量
压缩
  1. @echo off
  2. rem 保存为ansi编码
  3. rem 可选 m g
  4. set s=m
  5. set r1=40
  6. set r2=50
  7. set dirpath=d:\test
  8. if "%s%" equ "m" (
  9. set /a min=r1*1024*1024
  10. ) else if "%s%" equ "g" (
  11. for /f "delims=" %%a in ('powershell -c "%r1%*1024*1024*1024"') do set min=%%a
  12. ) else (
  13. exit
  14. )
  15. cd /d "%dirpath%"
  16. for /f "delims=" %%i in ('dir /b /s /a-d') do (
  17. set file=%%i
  18. set name=%%~dpni
  19. for /f "tokens=1-2 delims=." %%j in ('powershell -c "%%~zi/%min%"') do (
  20. setlocal enabledelayedexpansion
  21. if %%j equ 0 (
  22. rar a "!name!" -m0 "!file!"
  23. ) else (
  24. for /l %%l in (1,1,%%j) do (
  25. set /a "m=!random!%%(r2-r1)+r1,n=!random!%%90+10"
  26. set str=!str! -v!m!.!n!!s!
  27. )
  28. rar a "!name!" !str! -v!r2!!s! -m0 "!file!"
  29. )
  30. endlocal
  31. )
  32. )
  33. pause
复制代码



解压

  1. @echo off
  2. rem 保存为ansi编码
  3. set dirpath=d:\test
  4. cd /d "%dirpath%"
  5. for /f "delims=" %%i in ('dir /b /s /a-d "*part1.rar" "*part01.rar" "*part001.rar"') do (
  6. rar e "%%i" "%%~dpi"
  7. if not errorlevel 1 (
  8. set filepath=%%~dpi
  9. set name=%%~nxi
  10. setlocal enabledelayedexpansion
  11. for %%a in (part001.rar part01.rar part1.rar) do (
  12. set name=!name:%%a=!
  13. )
  14. del "!filepath!\!name!part*.rar"
  15. endlocal
  16. )
  17. )
  18. for /f "delims=" %%i in ('dir /b /s /a-d *.rar ^| find /i /v "part"') do (
  19. rar e "%%i" "%%~dpi" && del "%%i"
  20. )
  21. pause
复制代码

作者: czjt1234    时间: 2024-10-15 21:19

回复 12# 77七


    刚看了下7z的帮助文档,7z也支持多个-v参数的
作者: 304802301    时间: 2024-10-26 18:07

本帖最后由 304802301 于 2024-10-27 01:23 编辑

回复 11# flashercs


    老哥,Q3有几个小问题:
1、硬盘容量足够,所以不需要拆分/合并后删除源文件,能不能帮忙改下,不删除源文件。
2、拆分的时候,可以指定拆分后的文件存放路径
3、合并的时候,可以指定合并后的文件存放路径
4、原贴里写的是分割后文件命名方式是【原文件名-000001】,发现和我源文件名称有时候有点冲突,所以分割后重命名为【源文件+000001】,合并的时候也同步识别这个文件名。比如源文件名为【s760-nk.bak】,分割后是【s760-nk+000001.bak】
作者: flashercs    时间: 2024-11-3 21:55

回复 14# 304802301


    已修改了.




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2