我正在努力为我工作的公司存档很多文件。我对Batch脚本有点熟悉,但我还不太了解完全了解我的目标。
我正在尝试将基于文件名开头的一些文件复制到NAS上的文件夹中。这些文件是7z文件,它们的结构如下:
等
文件结构的工作原理如下:开头的四个数字是我们公司的工号。在我们的NAS上,我们有一个存档目录,其中包含文件夹:
这些文件夹中包含每个包含250个存档文件的文件夹。它们的格式如下:
我希望创建一个Batch文件,我可以将这些7z文件拖到它上面,它将读取文件名的前四个数字,并将其复制到我们NAS上的正确文件夹中。
例如文件:
将复制到
\ nas01 \ archive \ _5000-5999 \ _5250-5499
等。
我正在弄乱的主要代码是:
@echo off
for /f "delims=" %%i in ('dir /b /a-d *.7z') do (
set "filename1=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename1:~0,4!"
mkdir "!folder1!" 2>nul
copy "!filename1!" "!folder1!" >nul
)
对我来说不起作用的是这一行:
set "folder1=!filename1:~0,4!"
如何创建某种变量来检查文件名,必要时创建文件夹并将其复制到正确的文件夹?我将不胜感激任何帮助!
-Dustin
答案 0 :(得分:1)
感谢评论者的一些帮助,我能够弄清楚。我遇到了如何构建脚本的问题,但我明白了!
Option Explicit
Sub MixColumns()
Dim ws As Worksheet
Dim rngIn As Range
Dim rngOut As Range
Dim lng As Long
Dim rngArea As Range
Dim rngCell As Range
Set ws = ThisWorkbook.Worksheets("Sheet1")
' example 1
Set rngIn = ws.Range("B1:C1,E1:F1,G1") '<-- 5 cells, non-contiguous, forward order
Set rngOut = ws.Range("B2:F2") '<-- 5 contiguous cells
rngIn.Copy rngOut '<-- works
' example 2 - OP problem
Set rngIn = ws.Range("E1:F1,G1,B1:C1") '<-- 5 cells, non-contiguous, odd order
Set rngOut = ws.Range("B3:F3") '<-- 5 contiguous cells
rngIn.Copy rngOut '<-- should be e,f,g,b,c but gets b,c,e,f,g
' example 3 - solution for OP problem
Set rngIn = ws.Range("E1:F1,G1,B1:C1") '<-- 5 cells, non-contiguous, odd order
Set rngOut = ws.Range("B4:F4") '<-- 5 contiguous cells
lng = 1 '<-- rngOut cell counter
' iterate areas
For Each rngArea In rngIn.Areas
' iterate cells in area
For Each rngCell In rngArea.Cells
rngOut.Cells(1, lng).Value = rngCell.Value '<-- copy single value
lng = lng + 1 '<-- increment rngOut counter
Next rngCell
Next rngArea '<-- results in e,f,g,b,c
End Sub
我今天学到了更多关于Batch的知识,所以这是花了一天时间!
有没有办法让你可以点击并将文件拖到这个批处理脚本而不是抓取文件夹中的所有7z文件?
答案 1 :(得分:1)
以下是此任务的完整批处理代码,主要使用算术表达式和字符串连接来确定源文件夹中每个* .7z文件的目标文件夹路径,或者对于通过参数将名称传递给的每个文件。批处理文件。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Source path is the directory of the batch file ending with a backslash.
set "SourcePath=%~dp0"
rem Target path is a UNC path also ending with a backslash.
set "TargetPath=\\nas01\archive\"
rem Run subroutine ProcessFile for each *.7z file in source folder
rem if not at least 1 file was specified on command line to process.
rem Otherwise process the files of which names are passed as arguments
rem to this batch file on starting it.
if "%~1" == "" (
for %%I in ("%SourcePath%*.7z") do call :ProcessFile "%%I"
) else (
for %%I in (%*) do call :ProcessFile "%%~I"
)
rem Restore previous environment and exit this batch file.
endlocal
goto :EOF
rem The subroutine ProcessFile determines the target folders based on
rem first part of the file name separated with one or more spaces from
rem rest of the file name which should be a positive integer number.
rem File names not starting with a valid number are copied (or moved)
rem to the folder _0000-0249\_0000-0249 in specified target folder.
rem For file numbers less than 1000 an extra code is added to copy (or move)
rem those files into folders also having at least 4 digit numbers in name.
:ProcessFile
for /F %%J in ("%~n1") do set "FileNumber=%%J"
set /A FolderNumber1=(FileNumber / 1000) * 1000
set /A FolderNumber2=FolderNumber1 + 999
set /A FolderNumber3=FileNumber - FolderNumber1
if %FolderNumber3% LSS 250 (
set "FolderNumber3=%FolderNumber1%"
set /A FolderNumber4=FolderNumber1 + 249
goto BuildFolderPath
)
if %FolderNumber3% LSS 500 (
set /A FolderNumber3=FolderNumber1 + 250
set /A FolderNumber4=FolderNumber1 + 499
goto BuildFolderPath
)
if %FolderNumber3% LSS 750 (
set /A FolderNumber3=FolderNumber1 + 500
set /A FolderNumber4=FolderNumber1 + 749
goto BuildFolderPath
)
set /A FolderNumber3=FolderNumber1 + 750
set "FolderNumber4=%FolderNumber2%"
:BuildFolderPath
if %FolderNumber1% == 0 (
set "FolderNumber1=0000"
set "FolderNumber2=0%FolderNumber2%"
set "FolderNumber4=0%FolderNumber4%"
if %FolderNumber3% == 0 (
set "FolderNumber3=0000"
) else (
set "FolderNumber3=0%FolderNumber3%"
)
)
set "TargetFolder=%TargetPath%_%FolderNumber1%-%FolderNumber2%\_%FolderNumber3%-%FolderNumber4%"
mkdir "%TargetFolder%" 2>nul
copy /Y "%~1" "%TargetFolder%\" >nul
rem move /Y "%~1" "%TargetFolder%\" >nul
goto :EOF
使用子程序而不是在 FOR 循环中执行所有操作,因为这使得任务更容易编码,因为 GOTO 可以在子例程中使用。使用子程序时,没有必要使用延迟的环境变量扩展,这在* .7z文件包含感叹号的情况下很有用。
此解决方案的主要优点:它适用于文件名中范围为0到2147482999的数字。
要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。
call /?
copy /?
echo /?
endlocal /?
for /?
goto /?
if /?
mkdir /?
move /?
rem /?
setlocal /?
另请阅读Microsoft有关Using Command Redirection Operators解释>nul
和2>nul
的文章,该文章用于将成功和错误消息重定向到设备 NUL 以禁止它们。