我大约有18万个文件,需要根据文件名移至文件夹。 文件具有不同的扩展名。我需要获取所有以数字开头的文件名,并获取数字直到第一个“-”并创建一个文件夹。用文件夹中的数字移动所有文件。 需要排除不以数字开头的文件。
样本数据:文件名
123-ACBDHDJ.pdf 123-dhdjd.txt 5658-dgdjdk.txt 456477-gse.docx
例如;根据上面文件名中提到的上述数据,我想执行以下操作:
尝试以下脚本:
@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
当前面临的问题:
由于此数据量非常大,因此请使用批处理脚本来帮助您执行此操作或以更快的方式执行此操作。预先感谢。
答案 0 :(得分:0)
您正在使用许多不必要的代码,这会使您的批处理文件太慢。我建议像这样:
@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 /?
的cmd输出。
答案 1 :(得分:0)
让我们考虑一下为什么要花很长时间。您有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
答案 2 :(得分:0)
您可能已经对.bat文件脚本有了答案。这是在PowerShell中执行此操作的方法。测试脚本并正确移动文件后,请从-WhatIf
cmdlet中删除Move-Item
。
$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
}
}
这可以从cmd shell运行,方法是将脚本保存到文件(thefile.ps1)中,并使用以下命令或将该命令放入.bat文件脚本中。
powershell -NoLogo -NoProfile -File thefile.ps1
答案 3 :(得分:0)
我将通过以下方式进行操作-请查看代码中的所有解释性说明(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
命令!