如何根据每个文件名中留给固定分隔符字符串的字符串将文件移动到文件夹?
How to move files to folders based on string left to a fixed separator string in each file name?
例如我有一个名为的文件夹:
FIRSTNAME LASTNAME
我有文件:
FIRSTNAME LASTNAME CHK#123
FIRSTNAME LASTNAME CHK#145
我想批量自动移动所有文件。我有另一个 post:
的代码
@echo off
setlocal enabledelayedexpansion
pushd "C:\Folders\"
for %%a in (*) do (
set fldr=%%~na
set fldr=!fldr:~0,4!
md "!fldr!"
move "%%a" "!fldr!"
)
popd
pause
exit
但如果文件超过四个字符,它会创建一个包含前四个字符的文件夹。
我想要做的是批处理文件评估文件名,在分隔符字符串 CHK#
处停止,然后根据文件名左侧的名字和姓氏将文件移动到文件夹 [=13] =].
将文件名拆分成多个部分的一种方法是使用 space 和 #
作为 delims
并检查第三个标记是否为 CHK
:: Q:\Test19\SO_55462032.cmd
@echo off
setlocal enabledelayedexpansion
pushd "C:\Folders\"
for %%F in ("* * CHK#*") do for /f "tokens=1-4 delims=# " %%A in ("%%F") Do (
if "%%C"=="CHK" (
if not Exist "%%A %%B" MD "%%A %%B"
Move "%%F" "%%A %%B"
) else if "%%D"=="CHK" (
if not Exist "%%A %%B %%C" MD "%%A %%B %%C"
Move "%%F" "%%A %%B %%C"
)
)
popd
pause
exit /b
示例输出:
> SO_55462032.cmd
1 Datei(en) verschoben.
Drücken Sie eine beliebige Taste . . .
> tree a:\ /F
├───FIRSTNAME LASTNAME
│ FIRSTNAME LASTNAME CHK#123
│ FIRSTNAME LASTNAME CHK#145
│
└───Firstname Middlename Lastname
Firstname Middlename Lastname CHK#987
使用 RegEx 的 PowerShell 解决方案通过使用
获取 CHK#
前面的文件名部分
lookahead zerolength assertion
## Q:\Test19\SO_55462032.ps1
Pushd "C:\Folder"
Get-ChildItem *CHK#* -File | Where Name -match '^(.*)(?= CHK#)' | ForEach-Object {
If(!(Test-Path $Matches[1])){New-Item -ItemType Directory -Name $Matches[1]}
$_ | Move-Item -Destination $Matches[1]
}
PopD
示例输出:
> tree /F
├───FirstName
│ FirstName CHK#654
│
├───FIRSTNAME LASTNAME
│ FIRSTNAME LASTNAME CHK#123
│ FIRSTNAME LASTNAME CHK#145
│
├───Firstname Middlename Lastname
│ Firstname Middlename Lastname CHK#987
│
└───Title Firstname MiddleName Lastname
Title Firsname MiddleName Lastname CHK#159
这是针对此任务的简单批处理文件解决方案:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in ("C:\Folders\* CHK#*") do call :ProcessFile "%%I"
endlocal
goto :EOF
:ProcessFile
set "FileName=%~nx1"
set "CheckSum=%FileName:* CHK#= CHK#%"
call set "FolderName=%%FileName:%CheckSum%=%%"
md "%~dp1%FolderName%" 2>nul
move /Y %1 "%~dp1%FolderName%"
goto :EOF
CHK#
后的字符串不能有等号或一个或多个百分号。
子例程 ProcessFile
将字符串部分从第一次出现 CHK#
开始到文件名末尾分配给环境变量 CheckSum
.
再使用一个字符串替换从文件名中删除校验和字符串以获得文件夹名称。此命令行由 Windows 命令处理器双重解析,因为命令 call
在第一次解析时用环境变量 CheckSum
的当前值替换 %CheckSum%
并替换两者 %%
只差一个 %
。在第二次解析时,将处理剩余的 set "FolderName=%FileName: CHK#123=%"
,从而将第一个文件名示例的字符串 FIRSTNAME LASTNAME
分配给环境变量 FolderName
。另见 How does the Windows Command Interpreter (CMD.EXE) parse scripts?
要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
echo /?
endlocal /?
for /?
goto /?
另见
md /?
move /?
set /?
setlocal /?
例如我有一个名为的文件夹:
FIRSTNAME LASTNAME
我有文件:
FIRSTNAME LASTNAME CHK#123 FIRSTNAME LASTNAME CHK#145
我想批量自动移动所有文件。我有另一个 post:
的代码@echo off
setlocal enabledelayedexpansion
pushd "C:\Folders\"
for %%a in (*) do (
set fldr=%%~na
set fldr=!fldr:~0,4!
md "!fldr!"
move "%%a" "!fldr!"
)
popd
pause
exit
但如果文件超过四个字符,它会创建一个包含前四个字符的文件夹。
我想要做的是批处理文件评估文件名,在分隔符字符串 CHK#
处停止,然后根据文件名左侧的名字和姓氏将文件移动到文件夹 [=13] =].
将文件名拆分成多个部分的一种方法是使用 space 和 #
作为 delims
并检查第三个标记是否为 CHK
:: Q:\Test19\SO_55462032.cmd
@echo off
setlocal enabledelayedexpansion
pushd "C:\Folders\"
for %%F in ("* * CHK#*") do for /f "tokens=1-4 delims=# " %%A in ("%%F") Do (
if "%%C"=="CHK" (
if not Exist "%%A %%B" MD "%%A %%B"
Move "%%F" "%%A %%B"
) else if "%%D"=="CHK" (
if not Exist "%%A %%B %%C" MD "%%A %%B %%C"
Move "%%F" "%%A %%B %%C"
)
)
popd
pause
exit /b
示例输出:
> SO_55462032.cmd
1 Datei(en) verschoben.
Drücken Sie eine beliebige Taste . . .
> tree a:\ /F
├───FIRSTNAME LASTNAME
│ FIRSTNAME LASTNAME CHK#123
│ FIRSTNAME LASTNAME CHK#145
│
└───Firstname Middlename Lastname
Firstname Middlename Lastname CHK#987
使用 RegEx 的 PowerShell 解决方案通过使用
获取 CHK#
前面的文件名部分
lookahead zerolength assertion
## Q:\Test19\SO_55462032.ps1
Pushd "C:\Folder"
Get-ChildItem *CHK#* -File | Where Name -match '^(.*)(?= CHK#)' | ForEach-Object {
If(!(Test-Path $Matches[1])){New-Item -ItemType Directory -Name $Matches[1]}
$_ | Move-Item -Destination $Matches[1]
}
PopD
示例输出:
> tree /F
├───FirstName
│ FirstName CHK#654
│
├───FIRSTNAME LASTNAME
│ FIRSTNAME LASTNAME CHK#123
│ FIRSTNAME LASTNAME CHK#145
│
├───Firstname Middlename Lastname
│ Firstname Middlename Lastname CHK#987
│
└───Title Firstname MiddleName Lastname
Title Firsname MiddleName Lastname CHK#159
这是针对此任务的简单批处理文件解决方案:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in ("C:\Folders\* CHK#*") do call :ProcessFile "%%I"
endlocal
goto :EOF
:ProcessFile
set "FileName=%~nx1"
set "CheckSum=%FileName:* CHK#= CHK#%"
call set "FolderName=%%FileName:%CheckSum%=%%"
md "%~dp1%FolderName%" 2>nul
move /Y %1 "%~dp1%FolderName%"
goto :EOF
CHK#
后的字符串不能有等号或一个或多个百分号。
子例程 ProcessFile
将字符串部分从第一次出现 CHK#
开始到文件名末尾分配给环境变量 CheckSum
.
再使用一个字符串替换从文件名中删除校验和字符串以获得文件夹名称。此命令行由 Windows 命令处理器双重解析,因为命令 call
在第一次解析时用环境变量 CheckSum
的当前值替换 %CheckSum%
并替换两者 %%
只差一个 %
。在第二次解析时,将处理剩余的 set "FolderName=%FileName: CHK#123=%"
,从而将第一个文件名示例的字符串 FIRSTNAME LASTNAME
分配给环境变量 FolderName
。另见 How does the Windows Command Interpreter (CMD.EXE) parse scripts?
要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
call /?
echo /?
endlocal /?
for /?
goto /?
另见md /?
move /?
set /?
setlocal /?