Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am moving files based on their names to preset folders. I don't want to make new folders. So files should only be moved if the corresponding folder is existing already.

The file names all follow the same pattern: 1234_123456_AA_***********.(doc/pdf)

I have the following script below which works:

@echo on
for /r %%f in (*.*) do (
    echo processing "%%f"
    for /f "tokens=1-3 delims=_" %%a in ("%%~nxf") do (
        move "%%f" C:UsersxxxxxxxxxDesktopMOVEFILES\%%a_%%b_%%c
    )
)
pause

But the issue I am running into is that some of the files names have a '0' place holder in loop variable %%b, for example 1234_0123456_AA. But this file name should be interpreted like 1234_123456_AA and I want this file moved into the appropriate folder.

I have written this:

@echo on
SETLOCAL ENABLEDELAYEDEXPANSION
for /r %%f in (*.*) do (
    for /f "tokens=1-3 delims=_" %%a in ("%%~nxf") do (
        set z=%%b%
        echo !z:~-6!
        move "%%f" C:UsersxxxxxxxxxDesktopMOVEFILES\%%a_%%z_%%c
    )
)
pause

I get the echo to remove the '0' place holder, but need to get that back into %%b in the file path of where the file should be moved to.

What to modify in code to get the desired behavior?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
135 views
Welcome To Ask or Share your Answers For Others

1 Answer

Use the following code with the corrections of JosefZ applied and some additional improvements:

@echo off
setlocal EnableDelayedExpansion
for /R %%F in (*_*_*.*) do (
    for /F "tokens=1-3 delims=_" %%A in ("%%~nxF") do (
        set "MiddlePart=%%B"
        set "MiddlePart=!MiddlePart:~-6!"
        if exist "%USERPROFILE%DesktopMOVEFILES\%%A_!MiddlePart!_%%C*" (
            move /Y "%%F" "%USERPROFILE%DesktopMOVEFILES\%%A_!MiddlePart!_%%C"
        )
    )
)
endlocal
pause

The improvements on code are explained below in details.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • echo /?
  • endlocal /?
  • if /?
  • move /?
  • set /?
  • setlocal /?

1. Search pattern

The first improvement is the pattern used in first FOR as only files should be moved with at least 2 underscores in file name. This pattern is still not the best one, but good enough for this task.

2. Loop variable

It is better to use loop variables in upper case to avoid problems with the modifiers.

For example using as loop variable %%f and using inside the loop %%~f to use the string (must not be a file or folder name) of loop variable f without surrounding quotes, command processor exits batch processing with an error message because it expects one more letter, the loop variable as %%~f is interpreted as full name of file/folder of loop variable ?.

The loop variables and the modifiers are case sensitive. Therefore %%~F is interpreted by command processor as string of loop variable F without surrounding quotes and %%~fF as file/folder name with full path and extension of the file/folder of loop variable F.

Some other characters like # can be also used as loop variable.

3. Assigning value to environment variable with quotes

On assigning a string to an environment variable, it is always good to use

set "variable=text or other variable"

Using the quotes as shown here has the advantage that not visible spaces/tabs after last double quote are ignored by command processor.

But with using just

set variable=text or other variable

everything after first equal sign up to line termination is assigned to the variable including trailing spaces and tabs added perhaps by mistake on this line in the batch file. This is nearly never good and a common source of a batch execution problem which can be easily avoided by using quotes right.

Using the quotes as show below is also not good as in this case both double quotes are part of the text assigned to the variable (plus trailing spaces/tabs). This is sometimes useful, but is most often a coding mistake.

set variable="text or other variable"

4. Delayed expansion

Referencing a variable set or modified within a block defined with (...) requires delayed expansion if the current variable value should be used and not the value assigned to the variable above the block. Therefore using %%z was wrong in original code as variable z was not defined above first FOR loop and therefore was replaced always with nothing on execution of the loops.

5. Environment variable USERPROFILE

Running in a command prompt window set results in getting displayed all predefined environment variables for the current user account. There is the variable USERNAME, but also USERPROFILE containing path to the user′s profile directory with the Desktop folder and other user account related folders. Using environment variable USERPROFILE makes the batch file less dependent on Windows version and language of Windows.

ATTENTION:

The first FOR runs because of /R recursive on current directory and all its subdirectories. As the inner FOR loop moves all found files in current directory tree to subdirectories of %USERPROFILE%DesktopMOVEFILES, the current directory should be never any directory of this path.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...