batch file remove prefix of directory name - windows

I'm trying to remove a prefix of some directories.
I have many directories with names like '991234', '991235', '991236'. I want to remove the '99' from these folder names. The result needs to be a rename of the directories. They should be renamed to '1234', '1235', '1236'.
After some search I could write this script:
for /f "tokens=*" %%a in ('dir 99* /A:D /b') do ren "%%a" "00_%%a"
this script find all directories starting with '99' and call ren for each of them. The problem is that I could not remove the '99' part to apply in the folder name.

#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: I use a test directory name that includes spaces to verify that the routine works with such directorynames
:: Use SET "sourcedir=." for the current directory
SET "sourcedir=u:\your files\t w o"
for /f "tokens=*" %%a in ('dir /A:D /b "%sourcedir%\99*"') do SET "dirname=%%a"&ECHO ren "%sourcedir%\%%a" "!dirname:~2!"
GOTO :EOF
The metavariable %%a needs to be assigned to a user variable for manipulation. Since the user variable will change value within the code block, delayedexpansion needs to be invoked.
See for /? and set /? for documentation, as well as Stephan's DELAYEDEXPANSION link: https://stackoverflow.com/a/30284028/2128947
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 directories.
Always verify against a test directory before applying to real data.

Related

Batch file to find files in a directory

I am creating a batch file to find if any files are present in the path d:\Users\gladiator\Desktop\my docs.
If any files are present, I need to trigger an email stating which are the files present in that path.
This is the snippet of my batch script.
#echo off
for /f "delims=" %%F in ('dir /b /s "d:\Users\gladiator\Desktop\my docs"') do set MyVariable=%%F
echo %MyVariable%files are present
But this script is not displaying all the files present in that location.
Could someone help me to modify the script so as to display all the files present in the location?
Try to use setlocal enabledelayedexpansion to start a local environment before your loop, as described here:
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/setlocal
Then, after you're done, use endlocal
When you expand the variable MyVariable use !MyVariable! which is how "delayed expansion" within a local environment works (rather than %MyVariable%).
Microsoft does not allow modification of an environment variable with set variable=... within a loop, without using "delayed expansion."
Here is an example with your code:
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%F in ('dir /b /s "d:\Users\gladiator\Desktop\my docs"') do (
set MyVariable=%%F
echo !MyVariable! file is present
)
endlocal
This will at least allow you to see the files present. Beyond that I'm not sure what you wish to do once filenames are detected.
If you want to fill MyVariable with all files found, then you can do this
#echo off
setlocal enabledelayedexpansion
set MyVariable=
for /f "delims=" %%F in ('dir /b /s "d:\Users\gladiator\Desktop\my docs"') do (
set MyVariable=!MyVariable! %%F
)
echo !MyVariable! files found
endlocal

How to rename files in subfolder into a specific format

I have files named as RabcdYYMMKKACCOUNT.TXT in the Subfolders of a folder where YYMM is year, month this will change. KK is another identifier, I want all the files to be renamed to MSFKKDNB.ABC, the KK is the identifier in the input file.
Below is the one i tried and the result of it:
FOR /R %%f IN (*account.txt) DO REN "%%f" *dnb.abc
R00531706AUAccount.txt is renamed to R00531706AUAccount.txtdnb.abc
but the output should be MSFAUDNB.abc
This could be done for example with:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /R %%I in (???????????account.txt) do (
set "FileName=%%~nI"
set "NewFileName=MSF!FileName:~9,2!DNB.abc"
if not exist "%%~dpI!NewFileName!" (
ren "%%~fI" "!NewFileName!" 2>nul
if not exist "%%~dpI!NewFileName!" echo Failed to rename file: "%%~fI"
) else (
echo Cannot rename file: "%%~fI"
)
)
endlocal
The file name of found account text file is assigned to environment variable FileName.
The new name for the file is created by concatenating the fixed parts MSF and DNB.abc with the 2 characters to keep from file name using string substitution and delayed expansion.
Next it is checked if a file with new name does not already exist. Is this the case the file renaming is done otherwise an error message is output.
After renaming the file it is checked if that was successful. A slightly different error is output if renaming failed for example because of a sharing violation.
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 /?
for /?
if /?
ren /?
set /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators.
Try this:
#Echo Off
For %%A In ("*account.txt") Do (Set "_=%%~nA"
SetLocal EnableDelayedExpansion
Ren "%%A" "MSF!_:~-9,2!DNB.abc"
EndLocal)
I would probably do it the following way, provided that the files to rename are located in immediate sub-directories (YYMM) of the given root directory and nowhere else:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_ROOT=." & rem // (specify path to the root directory)
for /D %%D in ("%_ROOT%\????") do (
for %%F in ("%_ROOT%\%%~nxD\R??????????Account.txt") do (
set "FDIR=%%~nxD" & set "FILE=%%~nxF"
setlocal EnableDelayedExpansion
ECHO ren "!_ROOT!\!FDIR!\!FILE!" "MSF!FILE:~9,2!DNB.abc"
endlocal
)
)
endlocal
exit /B
If you want to check whether both the sub-directory name and the year/month portion of the file names are purely numeric, you could use the following script:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "_ROOT=." & rem // (specify path to the root directory)
for /F "delims= eol=|" %%D in ('
dir /B /A:D "%_ROOT%\????" ^| ^
findstr "^[0123456789][0123456789][0123456789][0123456789]$"
') do (
for /F "delims= eol=|" %%F in ('
dir /B /A:-D "%_ROOT%\%%~nxD\R??????????Account.txt" ^| ^
findstr "^R....[0123456789][0123456789][0123456789][0123456789].."
') do (
set "FDIR=%%~nxD" & set "FILE=%%~nxF"
setlocal EnableDelayedExpansion
ECHO ren "!_ROOT!\!FDIR!\!FILE!" "MSF!FILE:~9,2!DNB.abc"
endlocal
)
)
endlocal
exit /B
If you want to check whether the sub-directory name matches the year/month (YYMM) portion of the file names, replace the pattern R??????????Account.txt by R????%%~nxD??Account.txt (for both scripts).
After having verified the correct output of either script, remove the upper-case ECHO commands to actually rename any files!
Basically, both scripts use sub-string expansion to extract the identifier part (KK) from the file names. Since there are variables set and read in the same block of code, delayed expansion is required for that. The second approach does not list the sub-directories and files by standard for loops, it uses the dir command, findstr to filter their names and a for /F loop to capture the resulting output for both sub-directories and files.

Windows Batch File - Display All Folder & Sub-Folder relative paths

I am trying to have a batch file output ONLY the short-name of folders and sub-folders to a file. However, with the example below I am only able to get the fullpath.
DIR /S /B /O:N /A:D > FolderList.txt
Which will output:
X:\Example\Folder 1
X:\Example\Folder 2
X:\Example\Folder 3
X:\Example\Folder 1\Sub-Folder 1
X:\Example\Folder 1\Sub-Folder 2
X:\Example\Folder 2\Sub-Folder 1
When the desired output is:
Folder 1
Folder 2
Folder 3
Folder 1\Sub-Folder 1
Folder 1\Sub-Folder 2
Folder 2\Sub-Folder 1
The issue comes with the /S switch that allows the DIR command to recurse into sub-folders.
Is there a simple way, using only a Windows Batch File, to output a list of folders and sub-folders in the current directory to a text file?
#ECHO OFF
FOR /f "delims=" %%a IN ('DIR /S /B /O:N /A:D') DO (
SET "name=%%a"
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO(!name:%cd%\=!
endlocal
)
GOTO :EOF
made a little more confusing because you ask for the "short name" then describe the "relative name".
Obviously, name simply echoed to screen. You're aware of how to redirect.
Just to include a solution using a recursive function call approach
#echo off
setlocal enableextensions disabledelayedexpansion
call :getSubFolderList "%~1"
goto :eof
:getSubFolderList folder [prefix]
for /d %%a in ("%~f1.\*") do for %%b in ("%~2%%~nxa") do (
echo %%~b
call :getSubFolderList "%%~fa" "%%~b\"
)
goto :eof
When called with a starting folder, it will iterate over the list of subfolders, and for each one the subroutine will call itself to handle the descending folders.
The other answers to this question using echo to output the folder path use delayedexpansion, echoing the content of the variable used without any problem caused by the parser. But the code in this answer does not use delayed expansion, and characters as &() in the folder names can be a problem in the echo command.
To avoid this problem, the value to echo is quoted and wrapped inside a for replaceable parameter. That is the reason for the for %%b in the code.
To generate a file with the list of folders, the only change needed is, in the first call command:
call :getSubFolderList "%~1" > fileList.txt
note: the code in the answer has been written to receive the folder to be processed as the first argument to the batch file. Change "%~1" to your needs.
This uses a little trick with the old SUBST command to make the root folder a drive letter. Then you can use the FOR command modifiers to drop the drive letter from the variable on output.
#echo off
SET "folders=X:\Example"
subst B: "%folders%"
B:
(FOR /F "delims=" %%G in ('DIR /S /B /O:N /A:D') do echo %%~pnxG)>"%~dp0folderlist.txt
subst B: /D
Now obviously this does not check to make sure that the drive letter B: is available before using it. Easy enough to add some code to check for a drive letter that is not in use before executing the SUBST command.
To confirm my comment with regard the duplicate response:
#Echo Off
SetLocal EnableDelayedExpansion
For /L %%A In (1 1 8192) Do If "!__CD__:~%%A,1!" NEq "" Set/A "Len=%%A+1"
SetLocal DisableDelayedExpansion
(For /D /R %%A In (*) Do (
Set "AbsPath=%%A"
SetLocal EnableDelayedExpansion
Echo(!AbsPath:~%Len%!
EndLocal))>FolderList.txt

Copying files with name containing just numbers using a batchfile

I have a Directory with a deep Directory->Sub-directory tree structure. I need to write a batch file to copy all the numbered files (files with names as digits and no alphabetic characters) from all the sub-directories.
For example, a sub-directory might contain the following files:
WR10091.txt
AX10091.htm
10091.txt
AX10091.xml
10091.xml
I need to copy 10091.txt and 10091.xml to another location. I can copy files like AX10091.xml and AX10091.htm by specifying AX*.*. But I cannot figure out how to copy just numbered files with no alphabetic characters. There are thousands of directories and the directory structure does not have any pattern (the depth of a tree branch can vary considerably).
Any help will be appreciated.
#echo off
setlocal enableextensions disabledelayedexpansion
set "source=%cd%"
set "target=x:\target\folder"
for /r "%source%" %%a in (*) do (
(for /f "delims=0123456789" %%b in ("%%~na") do (
break
)) || echo copy "%%~fa" "%target%"
)
In this code the for %%a will iterate over all the files under the indicated folder. For each of them, the for /f %%b will try to tokenize the file name (%%~na) using numbers as delimiters. If the file name only contains numbers, there will be nothing to process (only delimiters) and the inner for raises errorlevel. This is checked with conditional execution (the code after the || is executed if the previous command fails) and if errorlevel was raised the copy operation is echoed to console.
If the output is correct, remove the echo to perform the copy.
note: the break in the inner for loop is included just to have a command that does nothing when files with non numeric names are found.
#echo off
for /f "tokens=* delims=" %%a in ('dir /b /s /a:-d "*"') do (
echo %%~na|findstr /e /b /r "[1-9]*" >nul 2>nul && (
copy %%~fa c:\somewhere\
)
)
should be executed in the same directory as the files.
for /f "delims=" %%a in ('dir /b/s/a-d ^| findstr /reic:"\\[0-9][0-9]*\..*" /c:"\\[0-9][0-9]*"') do copy "%%~a" "targetDir"
This might not work with XP and/or Vista, but this can be fixed if needed (see What are the undocumented features and limitations of the Windows FINDSTR command).

Trim Date from file name windows script

How do you trim the date from a text file. For example, I have multiple files like:
test_MX_abc_20091011.txt
test_MX_pqrdhdsu_20091011.txt
test_MX_xyieuz_20091011.txt
All files will have test_MX in common but the 3rd part will of different size.
I would like to change into:
test_MX_abc.txt
test_MX_pqrdhdsu.txt
test_MX_xyieuz.txt
I know how to change the file if name is like test_20091011.txt with the below code, But if name has more string along with date, how to do that?
for /F "tokens=1 delims=_" %%i in ("%%~na") do (
move /Y %%~fa %data_in%\%%i%%~xa >nul
)
Thanks in advance.
This rename operation can be done for example with:
#echo off
for /F "tokens=1-3* delims=_" %%A in ('dir /A-D /B test_MX_*.txt') do (
ren "%%A_%%B_%%C_%%D" "%%A_%%B_%%C.txt"
)
Each file name is separated into 4 strings assigned to loop variables A to D with using underscore as separator. The loop variable D takes everything of file name after third underscore.
Or also working for the 3 files:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%F in ('dir /A-D /B test_MX_*.txt') do (
set "ActFileName=%%~nF"
set "NewFileName=!ActFileName:~0,-9!"
ren "%%~F" "!NewFileName!.txt"
)
endlocal
This solution assigns the name of a file without file extension and path to environment variable ActFileName. Next a new environment variable with name NewFileName is defined with name of active file without the last 9 characters (underscore and date string). This modified file name is used next in the rename operation.
Other solutions using commands for, set and ren can be found on Stack Overflow.
Search with the string
[batch-file] for set rename files
and more than 600 results are presented all using more or less something like above.
For details on the used commands, open a command prompt window, execute one after the other following commands and read output help.
dir /?
for /?
ren /?
set /?

Resources