Truncate and rename subdirectories within a directory - batch-file

I have several folders named:
001TRIAL1
002TRIAL2
003TRIAL3
...etc.
I'm trying to rename all folders using a batch-file and truncate them in order to get:
TRIAL1
TRIAL2
TRIAL3
...etc.
I have tried this code:
for /D %%X in (C:\FOLDER1\FOLDER2\*) do (
move %%X %%X:~3,10%
)
Pause
But I'm unable to get the result I want.
This script does not work and I don't know how I can do that. The rename allows to rename folders but I'm not able to truncate the folders that I want.

You cannot expand a metavariable like that, you need to set the value to a proper variable, then perform the expansion. Additionally, as the variable would be set within a code block, you'd need to enable delayed expansion. Finally, you'd use Rename not Move, which would require that the directory already existed, and you'd need to delete the original directory post rename.
Try this:
#Echo Off
SetLocal DisableDelayedExpansion
For /D %%A In ("C:\FOLDER1\FOLDER2\*") Do (
Set "_d=%%~nxA"
SetLocal EnableDelayedExpansion
If Not Exist "%%~dpA!_d:~3!" Ren "%%A" "!_d:~3!"
EndLocal
)

Related

how to store and call variables in a batch script from command prompt in Windows

Based on this stackhowto, https://stackhowto.com/batch-file-to-list-folder-names/ ,
I tried to write a batch script that goes through all subfolders of a folder and renames .txt files based on the original folder name. However, I can't seem to actually store the name of the original folder and pass it along to rename the files, even though I can print them out directly just fine using echo %%~nxD.
My dummy folder structure looks like this:
Folder
subfolder
subsubfolder
test.txt
Where my batch script sits in the Folder.
The script I tried to use is pasted below.
It is supposed to run from within the Folder, go into each subfolder, save that subfolders name, then go into each subfolder within that subfolder, and rename any text files that contain the pattern by adding the subfoldername before the pattern in the filename.
However, the subfolder name is not properly saved, instead, what is returned from the echo %replace% is an empty string, and that is what the test.txt file will be renamed to: ".txt".
If I just type
echo %%~nxD
the folder name gets printed out correctly as expected, so it's the saving that isn't working
If I just add
set "replace=thisworksfine_%pattern%"
right at the beginning of this script after set "pattern=test",
then the file will be renamed into "thisworksfine_test.txt" as expected, so normal saving of a parameters works fine.
So clearly I am not understanding how one can save a variable in such a manner using these loops through folders.
Any help would be greatly appreciated!
setlocal enabledelayedexpansion
#echo off
set "pattern=test"
for /d %%D in (*) do (
cd %%~nxD
set "replace=%%~nxD_%pattern%"
echo %replace%
for /d %%D in (*) do (
cd %%~nxD
for %%I in (*.txt) do (
set "file=%%~I"
ren "%%I" "!file:%pattern%=%replace%!"
)
)
cd ..
)
cd ..
Thank you everyone, with those comments I got it to work, here is the (probably dirty by your standards) solution:
Basically use !! instead of %% to avoid delayed expansion, while also redefining the replace string at each level, and then using rename in the end instead of ren because that didn't seem to work with !replace3! inside of the argument.
setlocal enabledelayedexpansion
#echo off
set "pattern=test.txt"
for /d %%D in (*) do (
cd %%~nxD
set "replace=%%~nxD_%pattern%"
for /d %%D in (*) do (
set "replace2=!replace!"
cd %%~nxD
for %%I in (*.txt) do (
set "file=%%~I"
set "replace3=!replace2!"
echo !replace3!
rename %pattern% !replace3!
)
)
cd ..
)
cd ..

Recursively append folder name to the files in Windows batch file

I would like to append my folder name to all the available .txt files inside a subfolder. Below is the file/directory structure. I need to achieve this in Windows BATCH script.
C:\Source\Source1\1\a.txt C:\Source\Source1\1\b.txt
C:\Source\Source1\2\a.txt C:\Source\Source1\2\b.txt
C:\Source\Source2\3\a.txt C:\Source\Source2\3\b.txt
The above files should be renamed like below:
C:\Source\Source1\1\1_a.txt C:\Source\Source1\1\1_b.txt
C:\Source\Source1\2\2_a.txt C:\Source\Source1\2\2_b.txt
C:\Source\Source2\3\3_a.txt C:\Source\Source2\3\3_b.txt
Similary, I have Source1...Source30 and under each source directory, I will have multiple folders with different numbers. I need to rename all the files under these directories and append the number(directory name) to the file name.
So far below is what I wrote:
for %%* in (.) do set CurrDirName=%%~nx*
echo %CurrDirName%
for /r %%x in (*.txt) do ren "%%x" "%CurrDirName%_%%x"
With this, I am able to achieve it in a single directory. I couldn't make it recursive. Could you guys please help me with this.
#echo OFF
SETLOCAL EnableExtensions
for /F "delims=" %%G in ('dir /B /S "C:\Source\*.txt"') do (
for %%g in ("%%~dpG.") do ECHO rename "%%~fG" "%%~nxg_%%~nxG"
)
pause
where the FOR loops are:
outer %%G loop creates a static list of .txt files (recursively), and
inner %%g loop gets the parent folder of every particular file.
The rename command is merely displayed using ECHO for debugging purposes. To make it operational, remove word ECHO (no sooner than debugged).
Moreover, I'd consider checking whether a particular file is already renamed…

A duplicate file name exists, or the file cannot be found

I have seen previous issues here on it anyway, but I'm asking for the particular case at hand.
Currently trying to rename some files, but I actually want the file with the duplicate name to be overwritten.
#echo off
setlocal
for /R %%A in ("tgt*.nif") do (
set "fname=%%~A"
call ren "%%fname%%" "%%fname:*tgt=%%"
)
pause
Any suggestions?
EDIT: As suggested, an example. Well this is not real, but simply putting it (Reading this it's not "simply" but pft):
I have two files, one which is TimeGoog.pdf and another which is Goog.pdf. Now I have these variations of these two files in many folders, so it may be TimeToot.pdf and Toot.pdf. I want to rename all the TimeGoog.pdf to Goog.pdf, deleting the old Goog.pdf at the same time as it's been overwritten.
The script above does that, except because it's renaming to something that's already there, it won't do it. Note that the batch code I put above would work in the parent folder, and all the sub folders would take effect.
#echo off
setlocal enableextensions disabledelayedexpansion
for /r %%A in ("tgt*.nif") do (
set "folder=%%~dpA"
set "fileName=%%~nxA"
setlocal enabledelayedexpansion
echo move /y "!folder!!fileName!" "!folder!!fileName:*tgt=!"
endlocal
)
pause
This helped me : for renaming files with no extension, to files with a extension. (.csv)
ren *.* *.csv (wrong)
gives : A duplicate file name exists, or the file cannot be found
ren *.* *.*csv (works)
Works.

CMD: Script to batch rename files in a folder based upon the first 8 characters of its name

I am trying to rename dbf files in a folder. The batch script below is currently set up to rename the file to its current name. How do I modify the syntax to rename the files with just the first 8 characters, including the .dbf extension? I’ve tried using “%%~nx:~8.dbf” for the destination name, but it doesn’t seem to work. Thank you!
for %%x in ("C:\Users\user\Documents\monthly_adhoc\importclm\*.dbf") do (
rename "%%x" "%%~nx.dbf")
The input files would be something like this:
12345678_XXXXXXX_KKKKKK.dbf
12364178_XXXXXXX_KKKKKK.dbf
12124668_XXXXXXX_KKKKKK.dbf
12342178_XXXXXXX_KKKKKK.dbf
I’d want the output files to be this.
12345678.dbf
12364178.dbf
12124668.dbf
12342178.dbf
This should do it.
#echo off
setlocal EnableDelayedExpansion
for %%x in ("C:\Users\user\Documents\monthly_adhoc\importclm\*.dbf") do (
set newname=%%~nx
ren "%%x" "!newname:~0,8!.dbf"
)
You need an interim variable (FileName) for extracting the first 8 characters of each filename:
setlocal EnableDelayedExpansion
for %%X in ("C:\Users\user\Documents\monthly_adhoc\importclm\*.dbf") do (
set FileName=%%~nX
rename "%%~X" "!FileName:~0,8!%%~xX")
endlocal
The setlocal/endlocal block enables delayed expansion.
Take a look at this post for an explanation.

adding dates to copied files

I am trying to add the dates to copied files from one directory to another directory. This is how it should look like
Original file name: XEsalary.csv
Result file name: XEsalary-2013-02-15.csv
Here is my code:
set REMOTE=U:\
set LOG=C:\Integration\FE\log_test
set PVM=%DATE:~9,4%-%DATE:~6,2%-%DATE:~3,2%
set YY=%DATE:~9,4%
set LOCAL=C:\FTP\VC\test
cd %LOCAL%
xcopy /y /f /v "%LOCAL%\*.csv" "%REMOTE%\" >>%LOG%\%PVM%.log
xcopy /y /f /v "%LOCAL%\*.csv" "%LOCAL%\archive\*.csv"
:: assist with turning this into a for loop
ren %LOCAL%\archive\*.csv %LOCAL%\archive\*%PVM%.csv
echo. >>%LOG%\%PVM%.log
copying works just file. It is the renaming part which is not working. Any help please?
Thx in advance :-)
Using wildcards with RENAME is tricky. There is no good official documentation, but I have experimented and published rules as to how it works: See How does the Windows RENAME command interpret wildcards?
You can accomplish your rename with the following command, as long as none of your file names include dots (the last extension dot is OK).
ren "%LOCAL%\archive\*.csv" ????????????????????-%PVM%*
The number of ? must be greater than or equal to the longest name in the folder.
The result will be incorrect if a file name contains a dot. For example, part1.part2.csv would become part1-2013-02-15.part2.csv.
Another option is to use a FOR loop. You can safely append the date to any file using this technique.
for %%F in ("%LOCAL%\archive\*.csv") do ren "%%F" "%%~nF-%PVM%%%~xF"
BUT, both solutions have a problem if you rerun the process on a later date. New files will be added to the archive, but both new and old archive files will be renamed to the current date. That won't work.
Better to copy and rename the file in one step using a FOR loop as suggested in rojo's answer.
Or better yet, create a new archive folder with the date in the folder name, and then copy the files to the dated archive folder without renaming :-)
set REMOTE=U:\
set LOG=C:\Integration\FE\log_test
set PVM=%DATE:~9,4%-%DATE:~6,2%-%DATE:~3,2%
set YY=%DATE:~9,4%
set LOCAL=C:\FTP\VC\test
cd %LOCAL%
xcopy /y /f /v "%LOCAL%\*.csv" "%REMOTE%\" >>%LOG%\%PVM%.log
md "%LOCAL%\archive\%PMV%
xcopy /y /f /v "%LOCAL%\*.csv" "%LOCAL%\archive\%PVM%"
You might want to include the time in the folder name if the process could be run multiple times in the same day.
Windows doesn't let you rename with a wildcard. You have to name each file in a for loop. Might as well do the renaming as you're copying. Does this do what you intended?
#echo off
setlocal
set REMOTE=U:\
set LOG=C:\Integration\FE\log_test
set PVM=%DATE:~9,4%-%DATE:~6,2%-%DATE:~3,2%
set YY=%DATE:~9,4%
set LOCAL=C:\FTP\VC\test
xcopy /y /f /v "%LOCAL%\*.csv" "%REMOTE%\" >>%LOG%\%PVM%.log
pushd "%LOCAL%"
for %%I in (*.csv) do (
rem Uncomment the following line to log the copy to archive.
rem echo copy "%%I" -^> "%LOCAL%\archive\%%~nI-%PVM%.csv" >>%LOG%\%PVM%.log
copy "%%I" "%LOCAL%\archive\%%~nI-%PVM%.csv">NUL
)
echo. >>%LOG%\%PVM%.log
popd

Resources