Can someone please tell me what's wrong with this FOR loop?

天大地大妈咪最大 提交于 2021-02-11 12:40:59

问题


Apologies if duplicate, but no other answers so far have helped.

All I'm trying to do is loop through the files in a folder, and rename the last part of the file/extension.

Simply put - there could be 1-90 files, [filename]_01 - [filename]_90, and each day (via windows event scheduler) the number has to increment by one.

Nothing I do seems to achieve this.

The files are also meant to behave slightly differently when they hit certain milestones (30-60-90) but this I believe should already work if the variables update properly.

I have tried so many possible combinations of variable addressing (!variable!/%variable%/etc.) and while I can enter the loop, it does not repeat, nor update the variable number for the end of the files.

SetLocal EnableDelayedExpansion
set cnt=0
for %%A in (*) do set /a cnt+=1
set /A fileNumber = %cnt%-1
set /A newFileNumber = %cnt%
echo %fileNumber%
echo %newFileNumber%
for /l %%F in (%fileNumber%,1,1) do (
    if %newFileNumber%==90 (
        ren "*_%fileNumber%.don" "*_%newFileNumber%.csv"
        )
    if %newFileNumber%==60 (
        ren "*_%fileNumber%.don" "*_%newFileNumber%.csv"
        )
    if %newFileNumber%==60 (
        "ren *_%fileNumber%.don" "*_%newFileNumber%.csv"
        )
    ren "*_%fileNumber%.don" "*_%newFileNumber%.don"
    set fileNumber=%fileNumber%-1
    set newFileNumber=%newFileNumber%-1
    )

This should simply update all the files in the directory to increment by 1 in the file name. If anyone can point out where I'm going wrong I would really appreciate it.


回答1:


@ECHO OFF
SetLocal EnableDelayedExpansion
:: target directory name in variable for convenience.
SET "targetdir=U:\sourcedir"
:: switch to target directory
pushD "%targetdir%"
:: Start count at 100 so that it is 3 digits long
set cnt=100
dir
for %%A in (*) do set /a cnt+=1
set /A fileNumber = %cnt%
set /A newFileNumber = %cnt%+1
:: echoing last 2 characters (will be digits) of variables
echo %fileNumber:~-2% (%filenumber%)
echo %newFileNumber:~-2% (%newfilenumber%)
:: Assign %%F to values 100+actual descending by 1 to 101
for /l %%F in (%fileNumber%,-1,100) do (
 rem note need REM remarks within the loop
 REM use !varname! for current value of variable VARNAME
    if !newFileNumber:~-2!==90 (
        ECHO ren "*_!fileNumber:~-2!.don" "*_!newFileNumber:~-2!.csv"
        )
    if !newFileNumber:~-2!==60 (
        ECHO ren "*_!fileNumber:~-2!.don" "*_!newFileNumber:~-2!.csv"
        )
    if !newFileNumber:~-2!==30 (
        ECHO ren "*_!fileNumber:~-2!.don" "*_!newFileNumber:~-2!.csv"
        )
 rem Since you've just renamed (eg) _59.don to _60.csv, _59.don is missing  
    IF EXIST "*_!fileNumber:~-2!.don" ECHO ren "*_!fileNumber:~-2!.don" "*_!newFileNumber:~-2!.don"
    set /A fileNumber=fileNumber-1
    set /A newFileNumber=newFileNumber-1
    )
:: return to original directory
popd
GOTO :EOF

The required REN commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO REN to REN to actually rename the files.

Unfortunately, you've shown us HOW you've NOT been able to do some operation that's a little vague. We thus need to nut out what you intend to do, which is more work and prone to chasing wild geese.

You don't say what to do with files *_90, so we can't help there.

You appear to want to change *_59.don to *_60.csv, but your rename wants to change *_60.DON the next invocation, so unless the name has been changed from _*60.CSV back to *_60.DON, this isn't going to work.

Note that the basis of this routine is to work with the last two characters of variables. This is to accommodate the leading 0 you say is in your numbering scheme.

It's standard practice to assume that you will exercise any routine against a test directory for verification.

Note that every REN is ECHOed, so it is not EXECUTED, merely reported. Change the ECHO REN to REN to actually execute the command.

Note also that batch is largely case-insensitive. This means you don't have to wear out your SHIFT key unless you want to.




回答2:


To do math you have to use /A with SET

SET x=1
SET /A x=%x%+1
ECHO %x%

The /A switch specifies that the string to the right of the equal sign is a numerical expression that is evaluated. The expression evaluator is pretty simple and supports the following operations, in decreasing order of precedence:

For nested variables you need to use ! instead of %

SetLocal EnableDelayedExpansion

Setlocal EnableDelayedExpansion 
for /f %%G in ("abc") do ( 
    set _demo=%%G & echo !_demo!
)


来源:https://stackoverflow.com/questions/55418067/can-someone-please-tell-me-whats-wrong-with-this-for-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!