标题: [文件操作] 求助批处理修改文件名、识别文件夹名字后移动文件、分割文件 [打印本页]
作者: 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- @echo off
- rem 清单和批处理全部保存为ansi编码
- set list=d:\清单.txt
- set dirpath=d:\test
- cd /d "%dirpath%"
- for /f "delims=" %%i in ('dir /b /s ^| sort /r') do (
- for /f "tokens=1-2 delims=+" %%a in ('find /i "%%~ni" ^< "%list%"') do (
- if /i "%%~ni" equ "%%a" (
- if exist "%%i\" (
- ren "%%i" "%%b"
- ) else (
- ren "%%i" "%%b%%~xi"
- )
- )
- )
- )
- pause
复制代码
作者: 77七 时间: 2024-10-14 21:08
Q2- @echo off
- rem 批处理保存为ansi编码
- set folder=file
- set dirpath=d:\test
- cd /d "%dirpath%"
- for /f "delims=" %%i in ('dir /b /s /ad "%folder%"') do (
- move "%%i\*" "%%i\..\"
- )
- pause
复制代码
作者: czjt1234 时间: 2024-10-15 09:15
Q3 拆分文件- rem 另存为 ANSI 编码 bat
- ' & cls & cscript.exe /nologo /e:vbscript "%~f0" %* & pause & exit /b
-
- Option Explicit
- Dim oFSO, oWshShell, oStream1, oStream2, s, p, L, U, f
-
- p = "d:\1.db" '路径
- L = 40 '最小
- U = 50 '最大
-
- Set oFSO = CreateObject("Scripting.FileSystemObject")
- Set oWshShell = CreateObject("WScript.Shell")
- Set oStream1 = CreateObject("ADODB.Stream")
- oStream1.Type = 1 'adTypeBinary
- oStream1.Mode = 3 'adModeReadWrite
- Set oStream2 = CreateObject("ADODB.Stream")
- oStream2.Type = 1 'adTypeBinary
- oStream2.Mode = 3 'adModeReadWrite
- p = oFSO.GetAbsolutePathName(p)
- s = ""
- Call EnumFiles(p)
- For Each f In Split(Left(s, Len(s) - 2), vbCrLf)
- Call t(f)
- Next
- wsh.Echo "ok"
-
- Sub t(ByVal f)
- Dim i, size, n, t
- wsh.Echo f
- oWshShell.CurrentDirectory = oFSO.GetParentFolderName(f)
- oStream1.Open()
- oStream1.LoadFromFile f
- size = oStream1.Size
- If size <= L * 1024 * 1024 Then
- wsh.Echo "无需分解" & vbCrLf
- oStream1.Close()
- Exit Sub
- End If
- n = 0
- Do
- n = n + 1
- t = Right("000000" & n, 6)
- t = oFSO.GetBaseName(f) & "-" & t & "." & oFSO.GetExtensionName(f)
- Randomize
- i = Int((U - L + 1) * Rnd() + L)
- oStream2.Open()
- oStream1.CopyTo oStream2, i * 1024 * 1024
- oStream2.SaveToFile t, 2 'adSaveCreateOverWrite
- i = Int(oStream2.Size / 1024 / 1024)
- oStream2.Close()
- wsh.Echo i & "M →" & vbTab & t
- If oStream1.EOS Then
- oStream1.Close()
- wsh.Echo
- Exit Sub
- End If
- Loop
- End Sub
-
- Sub EnumFiles(ByVal folderPath)
- Dim oFile, oFolder 'oFSO, s 是全局变量
- On Error Resume Next '忽略无权限读取的文件夹和文件
- For Each oFile In oFSO.GetFolder(folderPath).Files
- s = s & oFile.Path & vbCrLf
- Next
- For Each oFolder In oFSO.GetFolder(folderPath).SubFolders
- Call EnumFiles(oFolder.Path)
- Next
- End Sub
复制代码
作者: qixiaobin0715 时间: 2024-10-15 09:34
本帖最后由 qixiaobin0715 于 2024-10-15 09:42 编辑
Q1
感觉楼主的这种修改文件名的方法,要想提高效率不是太容易。文件和文件夹分开重命名可能要好些,清单名称使用英文,可以尽量避免代码中出现中文,这样不容易出问题,比如list.txt:- @echo off
- setlocal enabledelayedexpansion
- for /f "tokens=1-2 delims=+" %%i in (list.txt) do set "_%%i=%%j"
- for /f "delims=" %%i in ('dir /s /b /ad^|sort /r') do if defined _%%~nxi ren "%%i" "!_%%~nxi!"
- for /f "delims=" %%i in ('dir /s /b /a-d') do if defined _%%~ni ren "%%i" "!_%%~ni!.%%~xi"
- pause
复制代码
作者: czjt1234 时间: 2024-10-15 09:40
本帖最后由 czjt1234 于 2024-10-15 10:59 编辑
回复 4# czjt1234
不行,ADODB.Stream只能处理小于2G的文件
楼主的文件太大了,要第三方软件来处理
- "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- @echo off
- set "list=.\清单.txt"
- set "dir0=C:\D\Test\ps1\要处理的文件夹"
-
- for /f "usebackq tokens=1* delims=+" %%A in ("%list%") do set "?%%~A=%%~B"
- for /f "delims=" %%A in ('dir /a-d-h /b /s "%dir0%"') do (
- if defined ?%%~nA (
- setlocal enabledelayedexpansion
- for %%B in ("!?%%~nA!") do (
- endlocal
- ren "%%~fA" "%%~B%%~xA"
- )
- )
- )
- for /f "delims=" %%A in ('dir /ad-h /b /s "%dir0%"^|sort /r') do (
- if defined ?%%~nxA (
- setlocal enabledelayedexpansion
- for %%B in ("!?%%~nxA!") do (
- endlocal
- ren "%%~fA" "%%~B"
- )
- )
- )
-
- pause
复制代码
Q2- @echo off
- set "file=文件夹名"
- set "dir0=C:\D\Test\ps1\要处理的文件夹"
-
- for /f "delims=" %%A in ('dir /ad-h /b /s "%dir0%"^|sort /r') do (
- if /i "%%~nxA"=="%file%" (
- move "%%~fA\*" "%%~dpA"
- )
- )
-
- pause
复制代码
Q3 分割- <#*,:
- @echo off
- cd /d "%~dp0"
- set "batchfile=%~f0"
- Powershell -ExecutionPolicy Bypass -C "Set-Location -LiteralPath ([Environment]::CurrentDirectory);. ([ScriptBlock]::Create([IO.File]::ReadAllText($env:batchfile,[Text.Encoding]::GetEncoding(0) )) )"
- pause
- exit /b
- #>
- $srcDir = "." # 要处理的文件夹路径 - 文件夹
- $filePattern = "*.db" # 要分割的文件类型
- $fragSizeRange = "40-50" # 文件分割容量范围,单位:MB
- $dstdir = ".\拆分后的目标路径" # 指定拆分后的文件存放路径
- $format = '{0}+{1:000000}{2}' # 拆分后的文件名格式
-
- $didst = [IO.Directory]::CreateDirectory($dstdir)
- $dirPath = $didst.FullName
- $buff = New-Object 'byte[]' -ArgumentList 64kb
-
- function Get-RandomSize {
- [double]$lo, [double]$hi = $fragSizeRange -split '-'
- $lo = $lo * 1mb
- $hi = $hi * 1mb
- if ($lo -eq $hi) {
- $m = $lo
- } elseif ($lo -gt $hi) {
- $m = Get-Random -Minimum $hi -Maximum $lo
- } else {
- $m = Get-Random -Minimum $lo -Maximum $hi
- }
- $m
- }
- (Get-ChildItem -Path ("$srcDir\*" -replace '[\[\]]', '`$&') -Filter $filePattern -Recurse | Where-Object { $_ -is [IO.FileInfo] -and $_.FullName -ne $env:batchfile }) | ForEach-Object {
- try {
- $_.FullName
- # $dirPath = [IO.Path]::GetDirectoryName($_.FullName)
- $ctr = 1
- $fragSize = Get-RandomSize
- $fragName = $format -f $_.BaseName, $ctr, $_.Extension
- $fragPath = [IO.Path]::Combine($dirPath, $fragName)
- if ($_.Length -le $fragSize) {
- $_.MoveTo($fragPath)
- return
- }
- $stream1 = New-Object System.IO.FileStream -ArgumentList ($_.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::Read, 64kb)
- $stream2 = New-Object System.IO.FileStream -ArgumentList ($fragPath, [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::None, 64kb)
- $totalSize = 0
- while (($readCount = $stream1.Read($buff, 0, $buff.Length)) -gt 0) {
- $stream2.Write($buff, 0, $readCount)
- $totalSize += $readCount
- if ($totalSize -ge $fragSize) {
- $stream2.Close()
- if ($stream1.Position -ge $stream1.Length) {
- break
- }
- $totalSize = 0
- ++$ctr
- $fragSize = Get-RandomSize
- $fragName = $format -f $_.BaseName, $ctr, $_.Extension
- $fragPath = [IO.Path]::Combine($dirPath, $fragName)
- $stream2 = New-Object System.IO.FileStream -ArgumentList ($fragPath, [IO.FileMode]::Create, [IO.FileAccess]::Write, [IO.FileShare]::None, 64kb)
- }
- }
- $stream1.Close()
- $stream2.Close()
- # 删除原文件
- # $_ | Remove-Item
- } finally {
- if ($stream1) { $stream1.Close(); $stream1 = $null; }
- if ($stream2) { $stream2.Close(); $stream2 = $null; }
- }
- trap {}
- }
复制代码
Q3 合并- @echo off
- @REM 要处理的文件夹
- set "dir0=."
- @REM 要合并的文件类型
- set "pattern=*+*.db"
- @REM 指定合并后的文件存放路径
- set "dir1=.\合并后的路径"
-
- md "%dir1%" 2>nul
- for /f "delims=" %%A in ('dir /a-h-d /b /s "%dir0%\%pattern%"') do (
- for /f "delims=+" %%B in ("%%~nA") do (
- if not defined ?%%~dpA%%~B (
- set "?%%~dpA%%~B=1"
- copy /b "%%~dpA%%~B+*%%~xA" "%dir1%\%%~B%%~xA"
- )
- )
- )
-
- pause
复制代码
作者: 77七 时间: 2024-10-15 20:02
winrar 可以指定分卷大小- 创建 卷 及大小 = <n> *1000
-
- 默认此参数使用 <n> 作为一千个 (1000) 字节 (非 1024 x 字节)。您也可以输入符号“k”来表示千字节的大小,或者符号“b”表示字节,在百万字节为 -‘m’,一百万个字节为 -‘M’ G 字节 - ‘g’十亿个字节 -‘G’。如果省略了大小,将会使用自动检测。
-
- 它允许使用十进位小数作为十进制的标记。例如,v1.5g 参数表示 1.5 GB。
-
- 您可以指定几个 -v 参数来为不同的卷设置不同的大小。例如 :
-
- WinRAR a -v100k -v200k -v300k arcname
复制代码
使用须把rar.exe添加到环境变量
压缩
- @echo off
- rem 保存为ansi编码
- rem 可选 m g
- set s=m
- set r1=40
- set r2=50
- set dirpath=d:\test
-
- if "%s%" equ "m" (
- set /a min=r1*1024*1024
- ) else if "%s%" equ "g" (
- for /f "delims=" %%a in ('powershell -c "%r1%*1024*1024*1024"') do set min=%%a
- ) else (
- exit
- )
- cd /d "%dirpath%"
- for /f "delims=" %%i in ('dir /b /s /a-d') do (
- set file=%%i
- set name=%%~dpni
- for /f "tokens=1-2 delims=." %%j in ('powershell -c "%%~zi/%min%"') do (
- setlocal enabledelayedexpansion
- if %%j equ 0 (
- rar a "!name!" -m0 "!file!"
- ) else (
- for /l %%l in (1,1,%%j) do (
- set /a "m=!random!%%(r2-r1)+r1,n=!random!%%90+10"
- set str=!str! -v!m!.!n!!s!
- )
- rar a "!name!" !str! -v!r2!!s! -m0 "!file!"
- )
- endlocal
- )
- )
- pause
复制代码
解压
- @echo off
- rem 保存为ansi编码
- set dirpath=d:\test
- cd /d "%dirpath%"
- for /f "delims=" %%i in ('dir /b /s /a-d "*part1.rar" "*part01.rar" "*part001.rar"') do (
- rar e "%%i" "%%~dpi"
- if not errorlevel 1 (
- set filepath=%%~dpi
- set name=%%~nxi
- setlocal enabledelayedexpansion
- for %%a in (part001.rar part01.rar part1.rar) do (
- set name=!name:%%a=!
- )
- del "!filepath!\!name!part*.rar"
- endlocal
- )
- )
- for /f "delims=" %%i in ('dir /b /s /a-d *.rar ^| find /i /v "part"') do (
- rar e "%%i" "%%~dpi" && del "%%i"
- )
- 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 |