如何根据每个文件名中固定分隔符字符串的左侧字符串将文件移动到文件夹?

时间:2019-04-01 19:13:33

标签: powershell batch-file move

例如,我有一个名为:

的文件夹
FIRSTNAME LASTNAME

我有文件:

FIRSTNAME LASTNAME CHK#123
FIRSTNAME LASTNAME CHK#145

我想进行批处理以自动移动所有文件。我从另一篇文章中获得了这段代码:

@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#上,然后根据文件名中的名字和姓氏将文件移动到文件夹中, CHK#

3 个答案:

答案 0 :(得分:1)

使用RegEx的PowerShell解决方案,通过使用
获得code.samp em:nth-of-type(2n+2) { background: #e7f2fa; } code.samp em{ color: #2980B9; } .cmdglossary div.line:nth-of-type(2n+2) { background: rgb(231, 242, 250); } 前面的文件名部分 lookahead zerolength assertion

CHK#

示例输出:

## Q:\Test\2019\04\01\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

答案 1 :(得分:1)

这是用于此任务的简单批处理文件解决方案:

@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=%",导致将第一个文件名示例的字符串FolderName分配给环境变量FIRSTNAME LASTNAME。另请参见How does the Windows Command Interpreter (CMD.EXE) parse scripts?

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

答案 2 :(得分:0)

将文件名拆分为多个部分的一种方法是使用空格和#作为delims
并检查第三个令牌是否为CHK

:: Q:\Test\2019\04\01\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