Implement Regex in batch or powershell script to generate folders and move files in relative folders ordered by key string in file name

前端 未结 1 1291
感动是毒
感动是毒 2021-01-29 06:52

I use a similar script to generate and move files into folders.

$ToFolder = \"$env:USERPROFILE\\Desktop\\to\"
$FromFolder = \"$env:USERPROFILE\\Desktop\\From\"

         


        
相关标签:
1条回答
  • 2021-01-29 07:38

    Here is a pure batch-file solution -- see all the explanatory remarks (rem):

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "SPLITCHAR=-"  & rem // (a single character to split the file names)
    set "SEARCHSTR=_"  & rem // (a certain string to be replaced by another)
    set "REPLACSTR= "  & rem // (a string to replace all found search strings)
    set "OVERWRITE="   & rem // (set to non-empty value to force overwriting)
    
    rem // Get file location and pattern from command line arguments:
    set "LOCATION=%~1" & rem // (directory containing files to process)
    set "PATTERNS=%~2" & rem // (file pattern; match all files if empty)
    
    rem /* Prepare overwrite flag (if defined, set to character forbidden
    rem    in file names; this affects later check for file existence): */
    if defined OVERWRITE set "OVERWRITE=|"
    rem // Continue only if location is given:
    if defined LOCATION (
        rem // Change current working directory to given location:
        pushd "%LOCATION%" && (
            rem // Loop through all files matching the given pattern:
            for /F "eol=| delims=" %%F in ('dir /B "%PATTERNS%"') do (
                rem // Process each file in a sub-routine:
                call :PROCESS "%%F" "%SPLITCHAR%" "%SEARCHSTR%" "%REPLACSTR%"
            )
            rem // Restore former working directory:
            popd
        )
    )
    
    endlocal
    exit /B
    
    
    :PROCESS
    rem // Retrieve first argument of sub-routine:
    set "FILE=%~1"
    rem // Split name at (first) split character and get portion in front:
    for /F "delims=%~2" %%E in ("%~1") do (
        rem // Append a split character to partial name:
        set "FOLDER=%%E%~2"
    )
    setlocal EnableDelayedExpansion
    rem // Right-trim partial name:
    if not "%~3"=="" set "FOLDER=!FOLDER:%~3%~2=!"
    set "FOLDER=!FOLDER:%~2=!"
    rem /* Check whether partial name is not empty
    rem    (could happen if name began with split character): */
    if defined FOLDER (
        rem // Replace every search string with another:
        if not "%~3"=="" set "FOLDER=!FOLDER:%~3=%~4!"
        rem // Create sub-directory (surpress error if it already exists):
        2> nul md "!FOLDER!"
        rem /* Check if target file already exists; if overwrite flag is
        rem    set (to an invalid character), the target cannot exist: */
        if not exist "!FOLDER!\!FILE!%OVERWRITE%" (
            rem // Move file finally (surpress `1 file(s) moved.` message):
            1> nul move /Y "!FILE!" "!FOLDER!"
        )
    )
    endlocal
    exit /B
    

    The script requires the directory containing all the files to process as the first command line argument. The created sub-directories are placed therein. An optional second command line argument defines a file name pattern to filter certain file types/names. Supposing it is saved as D:\Script\build-folder-hierarchy.bat, the files are contained in D:\Data, and you want to handle *.pdf files only, run it as follows:

    "D:\Script\build-folder-hierarchy.bat" "D:\Data" "*.pdf"
    

    This is a very similar approach, but with a slightly different directory handling:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here:
    set "SPLITCHAR=-"  & rem // (a single character to split the file names)
    set "SEARCHSTR=_"  & rem // (a certain string to be replaced by another)
    set "REPLACSTR= "  & rem // (a string to replace all found search strings)
    set "OVERWRITE="   & rem // (set to non-empty value to force overwriting)
    
    rem // Get file location and pattern from command line arguments:
    set "LOCATION=%~1" & rem // (directory to move the processed files into)
    set "PATTERNS=%~2" & rem // (file pattern; match all files if empty)
    
    rem /* Prepare overwrite flag (if defined, set to character forbidden
    rem    in file names; this affects later check for file existence): */
    if defined OVERWRITE set "OVERWRITE=|"
    rem // Continue only if target location is given:
    if defined LOCATION (
        rem // Create target location (surpress error if it already exists):
        2> nul md "%LOCATION%"
        rem /* Loop through all files matching the given pattern
        rem    in the current working directory: */
        for /F "eol=| delims=" %%F in ('dir /B "%PATTERNS%"') do (
            rem // Process each file in a sub-routine:
            call :PROCESS "%%F" "%LOCATION%" "%SPLITCHAR%" "%SEARCHSTR%" "%REPLACSTR%"
        )
    )
    
    endlocal
    exit /B
    
    
    :PROCESS
    rem // Retrieve first argument of sub-routine:
    set "FILE=%~1"
    rem // Split name at (first) split character and get portion in front:
    for /F "delims=%~3" %%E in ("%~1") do (
        rem // Append a split character to partial name:
        set "FOLDER=%%E%~3"
    )
    setlocal EnableDelayedExpansion
    rem // Right-trim partial name:
    if not "%~4"=="" set "FOLDER=!FOLDER:%~4%~3=!"
    set "FOLDER=!FOLDER:%~3=!"
    rem /* Check whether partial name is not empty
    rem    (could happen if name began with split character): */
    if defined FOLDER (
        rem // Replace every search string with another:
        if not "%~4"=="" set "FOLDER=!FOLDER:%~4=%~5!"
        rem // Create sub-directory (surpress error if it already exists):
        2> nul md "%~2\!FOLDER!"
        rem /* Check if target file already exists; if overwrite flag is
        rem    set (to an invalid character), the target cannot exist: */
        if not exist "%~2\!FOLDER!\!FILE!%OVERWRITE%" (
            rem // Move file finally (surpress `1 file(s) moved.` message):
            1> nul move /Y "!FILE!" "%~2\!FOLDER!"
        )
    )
    endlocal
    exit /B
    

    This script uses the current working directory to find the files to process. It requires the target directory as the first command line argument, where the created sub-directories are placed in. An optional second command line argument defines a file name pattern to filter certain file types/names. Supposing it is saved as D:\Script\build-folder-hierarchy.bat, the files are contained in D:\Data and need to be moved to D:\Target, and you want to handle *.pdf files only, run it as follows:

    cd /D "D:\Data"
    "D:\Script\build-folder-hierarchy.bat" "D:\Target" "*.pdf"
    
    0 讨论(0)
提交回复
热议问题