Search code examples
batch-filefile-rename

How to get a text file name in located in current directory to a variable with a batch file


I have a .txt file of which name is used as a reference with the format AS2204-1 according to the naming scheme ASyymm-sn with yy being the current year without century, mm being the current month and sn being a serial number with the current month. I try to get the current file name and increment the serial number by 1 on year and month unchanged, copy the new file name to the clipboard and then rename the text file.

This is my code so far:

@echo off
set yy=%date:~12,2%
set mm=%date:~4,2%
set /a sn=0

for %%a in ('dir *.txt') do (set filename=%%a)
set Fmm=%filename:~5,2%
if %Fmm%==%mm% (set /a sn=sn+1) else (set /a sn=1)
echo AS%yy%%mm%^-%sn% |clip 
ren "%filename%.txt"  "AS%yy%%mm%^-%sn%.txt"

I can't get the file name assigned to the variable filename.

What is wrong with my code and what would be a correct FOR loop?


Solution

  • @echo off
    setlocal
    pushd "?:\whichever\directory\contains your\target files"
    set "yy=%date:~12,2%"
    set "mm=%date:~4,2%"
    
    set "filename="    
    for /f %%a in ('dir /b /a-d /od AS%yy%%mm%-*.txt 2^>nul') do (set "filename=%%~na")
    rem use this line if you use suppressed leading zero
    if defined filename (set /a "sn=%filename:*-=%+1") else (set /a sn=1)
    rem use this line if you use 2-digit
    if defined filename (set /a "sn=1%filename:~-2%+1") else (set /a sn=101)
    
    IF %sn% gtr 100 SET "sn=%sn:~-2%"
    
    echo AS%yy%%mm%-%sn%
    ren "whatever.txt"  "AS%yy%%mm%-%sn%.txt"
    POPD
    goto :eof
    

    The setlocal ensures that the environment changes (new variables) are removed when the batch terminates.

    pushd switches to the specified directory. I've no idea what your directory is.

    The syntax SET "var=value" (where value may be empty; in which case var becomes undefined) is used to ensure that any stray trailing spaces are NOT included in the value assigned.

    The for /f assigns each line of the dir "report" to %%a in turn. In consequence, filename will be set to the name part only (%%~na) of the filename found. dir /b produces a list of files to be processed, in basic form (filename only). /a-d excludes directorynames, /od produces the list in date order. The filemask AS%yy%%mm%-*.txt asks for all .txt files which match AS+thecurrentyearnumber+thecurrentmonthnumber+-, so it's not necessary to check the year/month part. The 2^>nul suppresses error messages should no filename matching the mask be found.

    If a filename was found, filename will be defined. That's why it's set to nothing (which undefines it) before the for loop.

    The filenames must be produced in date order because ASyymm-10 will sort before ASyymm-2 in the default name-order list.

    Well, I've no idea whether you use 1- or 2-digit serial numbers - the processing is different.

    If you use the first if defined... then sn is set to 1 more than (that part of filename that exists when all characters up to the - are removed) or 1 if no prior file was found.

    If you use the second if defined... then sn is set to 1 more than (1+the last 2 characters of filename) or 101 if no prior file was found, so ASyymm-07 would produce sn=108. This is necessary because batch interprets a numeric string beginning 0 as OCTAL in calculations.

    if the result is >100, then use the last 2 characters of sn.

    I've just echoed the required string to the screen. Echo to the clipboard if you wish.

    Well - the rename. It's unclear what the file to be renamed to the calculated name is, so I've used whatever. Possibly it's a file named ASyymm.txt - if so, replace whatever with AS%yy%%mm%.

    The popd returns to the original directory.

    Documentation can be obtained by executing commandname /? for most commands but it can be a little cryptic at times. Simply search SO for examples.