簡體   English   中英

批處理:如何根據文件名將文件復制到目錄

[英]BATCH: How can I copy files to directory based on file name

我要為自己工作的公司歸檔很多文件。 我對批處理腳本有點熟悉,但是我對它的理解還不夠充分。

我正在嘗試根據文件名的開頭將一些文件復制到我們NAS上的文件夾中。 這些文件是7z文件,其結構將如下所示:

  • 5476寶馬把手-A.7z
  • 5487雪佛蘭-Imp.7z
  • 5986本田Lid-Upper.7z

等等

文件結構是這樣的:開頭的四個數字是我們公司的工作編號。 在我們的NAS上,我們有一個包含目錄的存檔目錄,如下所示:

  • _5000-5999
  • _6000-6999

在這些文件夾的內部,每個文件夾將包含250個存檔文件。 它們的格式如下:

  • _5000-5249
  • _5250-5499
  • _5500-5749
  • _5750-5999

我正在尋找一個可以將這些7z文件拖到其中的批處理文件,它將讀取文件名的前四個數字,並將其復制到我們NAS上的相應文件夾中。

因此,例如文件:

  • 5476寶馬把手-A.7z
  • 5487雪佛蘭-Imp.7z

將復制到

\\ 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

多虧了評論員的幫助,我才得以弄清楚。 我在如何構造腳本方面遇到問題,但是我明白了!

@echo off
for /f "delims=" %%i in ('dir /b /a-d *.7z') do (
set "filename=%%~i"
setlocal enabledelayedexpansion
set "folder1=!filename:~0,4!"
set "subfolder1=_!folder1:~0,1!000-!folder1:~0,1!999"
set "firstdigit=!filename:~0,1!"
set "parent=\\nas01\The_Archives"

REM CONDITIONAL STATEMENTS
IF !folder1! GEQ !firstdigit!000 IF !folder1! LEQ !firstdigit!249 SET "subfolder2=_!firstdigit!000-!firstdigit!249"
IF !folder1! GEQ !firstdigit!250 IF !folder1! LEQ !firstdigit!499 SET "subfolder2=_!firstdigit!250-!firstdigit!499"
IF !folder1! GEQ !firstdigit!500 IF !folder1! LEQ !firstdigit!749 SET "subfolder2=_!firstdigit!500-!firstdigit!749"
IF !folder1! GEQ !firstdigit!750 IF !folder1! LEQ !firstdigit!999 SET "subfolder2=_!firstdigit!750-!firstdigit!999"

mkdir "!parent!\!subfolder1!\!subfolder2!" 2>nul
copy "!filename!" "!parent!\!subfolder1!\!subfolder2!" >nul
)

我今天了解了有關Batch的更多信息,所以這是度過了愉快的一天!

有什么方法可以使我到這里,只需單擊文件並將其拖動到此批處理腳本中,而不是獲取文件夾中的所有7z文件?

這是此任務的完整批處理代碼,主要使用算術表達式和字符串連接來確定源文件夾中每個* .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文章,其中解釋了>nul2>nul用於將成功和錯誤消息重定向到設備NUL來抑制它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM