簡體   English   中英

Windows批處理腳本,用於根據用於巨大數據量的文件名將文件移動到其他文件夾

[英]Windows Batch Script for moving files to different Folders based on File Name for Huge Data Volume

我大約有18萬個文件,需要根據文件名移至文件夾。 文件具有不同的擴展名。 我需要獲取所有以數字開頭的文件名,並獲取數字直到第一個“-”並創建一個文件夾。 用文件夾中的數字移動所有文件。 需要排除不以數字開頭的文件。

樣本數據:文件名

 123-ACBDHDJ.pdf 123-dhdjd.txt 5658-dgdjdk.txt 456477-gse.docx 

例如; 基於上面文件名中提到的上述數據,我要執行以下操作:

  • 使文件夾123,5658456477
  • 移動文件夾123中的前兩個文件,文件夾5658中的第三個文件以及文件夾456477中的最后一個文件。

嘗試以下腳本:

@echo off
setlocal enabledelayedexpansion
for %%A in (*.psd *.jpg *.html *.tif *.xls *.xlsx *.htm *.csv *.pdf *.docx *.TXT *.zip *.msg *.xlsb *.eml *.*) do (
   echo file found  %%A
   for /f "delims=" %%B in ("%%A") do set fname=%%~nB
   for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
   for /f "tokens=1* delims=-" %%D in ("!fname!") do set folname=%%D
   echo folder name !folname!
   if not exist "!folname!" (
      echo Folder !folname! does not exist, creating
      md "!folname!"
   ) else (
      echo Folder !folname! exists
   )
   echo Moving file %%A to folder !folname!
   move "%%A" "!folname!"
   )
echo Finished
pause

當前面臨的問題:

  1. 文件夾也是用字母數字字符創建的,我想忽略這些文件,只選擇以數字開頭的文件。
  2. 腳本運行時間過長,性能非常慢。 數據量很高,有18萬條記錄。

由於此數據量非常大,因此請使用批處理腳本來幫助您執行此操作或以更快的方式執行此操作。 提前致謝。

您正在使用許多不必要的代碼,這會使您的批處理文件太慢。 我建議類似的東西:

@echo off

for %%A IN (*.*) do (
    if not "%%~fA" == "%~f0" (
        echo File found: %%A
        for /f "tokens=1* delims=-" %%B IN ("%%~nxA") do (
            md %%B>nul
            (move "%%~fA" "%%~dpA%%B")>nul
        )
    )
)
echo Finished
pause
exit /b %errorlevel%

您正在制作的其他循環似乎也沒有用。 您可以直接使用%%~nA%%~xA等,請參見for /?輸出for /? 以cmd為單位。

讓我們考慮一下為什么要花很長時間。 您有128k個文件,運行4個循環,這意味着for循環自己將每個文件處理5次,即單獨處理640 000個進程,然后為每個文件運行echo s,即更多的進程,然后檢查是否文件夾存在,如果沒有創建,則文件夾存在是另一個過程..我想您正在用這個方法。 您實際上正在運行一百萬個過程來完成此任務。

也許我們擺脫了所有不必要的for循環,使用*而不是為每個文件命名,然后擺脫了延遲擴展,因為我們無需設置變量就可以擺脫掉:

@echo off
for %%i in (*) do (
    echo file found  %%i
    for /f "tokens=1* delims=-" %%a in ("%%i") do (
     if "%%a-%%b"=="%%i" (
      md %%a>nul
      move "%%~fi" %%a
   )
  )
 )
echo Finished
pause

至於名稱和擴展名部分,則在設置后再也不會使用它們,如果您仍然想在某個地方使用文件的名稱和擴展名,那么您只需要使用它們而無需設置vars:

@echo off
for %%i in (*) do (
   echo file found  %%i
   for /f "tokens=1* delims=-" %%a in ("%%i") do (
    if "%%a-%%b"=="%%i" (
       md %%a>nul
       move "%%~fi" %%a
       echo This is the file extension: %%~xi
       echo This is the filename: %%~na
       echo This is the filename, drive and path: %%~dpi
       echo This is the filename with full path: %%~fi
   )
  )
 )
echo Finished
pause

.bat文件腳本可能已經有了答案。 這是在PowerShell中執行此操作的方法。 測試腳本並正確移動文件后,請從Move-Item cmdlet中刪除-WhatIf

$sourcedir = './s'
$destdir = './d'

Get-ChildItem -File -Path "$sourcedir/*" |
    ForEach-Object {
        if ($_.Name -match '^(\d+)-.*') {
            $ddir = Join-Path $destdir $Matches[1]
            if (-not (Test-Path -Path $ddir)) { New-Item -Name $ddir -ItemType Directory }
            Move-Item -Path $_.FullName -Destination $ddir -WhatIf
        }
    }

通過將腳本保存到文件(thefile.ps1)中並使用以下命令或將該命令放入.bat文件腳本,可以從cmd shell運行該命令。

powershell -NoLogo -NoProfile -File thefile.ps1

我將通過以下方式進行操作-參見代碼中的所有解釋性說明( rem ):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_ROOT=%~dp0." & rem /* (directory containing all the files; `%~dp0` points to the
                     rem     parent directory of this batch script; to use the current
                     rem     working directory, simply specify a single `.`) */
set "_MASK=?*-*.*" & rem /* (search pattern to find files, matching only files with at
                     rem     least one hyphen in their names) */
set "_FILTER=^[0123456789][0123456789]*-" & rem /* (`findstr` filter expression;
                     rem     this matches only files whose name begin with one or more
                     rem     decimal digits followed by a hyphen) */

rem // Change to given root directory:
pushd "%_ROOT%" && (
    rem // Loop through all matching files:
    for /F "tokens=1* delims=-" %%E in ('
        rem/ Return files and filter out those with non-numeric prefix: ^& ^
            dir /B /A:-D "%_MASK%" ^| findstr /R /I /C:"%_FILTER%"
    ') do (
        rem // Try to create target directory:
        ECHO md "%%E" 2> nul
        rem // Move file into target directory:
        ECHO move /Y "%%E-%%F" "%%E\"
    )
    rem // Return from root directory:
    popd
)

endlocal
exit /B

在測試腳本的正確輸出之后, 刪除兩個大寫的ECHO命令!

暫無
暫無

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

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