Renaming all folder name using batch script - windows

How to rename folder name using batch script ? I need to rename file name like:
a Filename1
b filename2
to
A
B
i.e make it uppercase and substring only to initial part.
So far I have come up with :
#echo "Renaming file"
for /D %%f in (C:\REN\*) do rename "%%f" "%%~nxf_myname"
pause

I'm assuming you actually want to rename folders found in C:\REN\, and not files.
I'm also assuming that by "initial part" you mean up until the first space character. If this is correct, then you want to use FOR /F to parse the name into tokens.
The SET search and replace functionality is case insensitive with regard to the search portion.
I'm creating variables for both the original and new names and I'm toggling delayed exapnsion on and off just in case the folder name contains a ! character. For variables are corrupted if value contains ! and delayed expansion is enabled.
#echo off
setlocal disableDelayedExpansion
echo Renaming folders
for /d %%F in (C:\REN\*) do (
for /f "eol= " %%A in ("%%~nxF") do (
set "name=%%F"
set "newName=%%A"
setlocal enableDelayedExpansion
for %%C in (
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
) do set "newName=!newName:%%C=%%C!"
ren "!name!" "!newName!"
endlocal
)
)

Related

batch file to search all drives for a specific file and delete that file

I'm trying to make a batch file to find a file (for example Raihan.txt) and delete it or forced delete it(if its running).
In this case I want it to search all drives including USB drives.
I actually don't know much about batch coding, I searched it on internet and came up with those line and problem is I can't search all drives. I need some help here.
#echo off
set file_to_delete=Raihan.txt
set dir_to_look_in=C:\
:: Starting loop
for /f "tokens=1* delims=" %%f in ('dir /s /o /b "%dir_to_look_in%" ^| findstr "%file_to_delete%"') do (
echo INFO: Deleting: %%f
del /q "%%f"
)
I haven't run it because it's not even complete, one wrong move and I will be in big trouble.
Here is one example
#echo off
set file_to_delete=Raihan.txt
:: Starting loop to search through all drives
for %%d in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
if exist "%%d:\%file_to_delete%" (
echo INFO: Deleting: "%%d:\%file_to_delete%"
del /q "%%d:\%file_to_delete%"
)
)
Here is another
#echo off
setlocal enabledelayedexpansion
set "file_name=Raihan.txt"
for /f "tokens=1-2" %%a in ('fsutil fsinfo drives ^| findstr /r "^[A-Z]:"' ) do (
if exist "%%a:\%file_name%" (
echo Deleting "%%a:\%file_name%"
del "%%a:\%file_name%"
)
)
#echo off
setlocal enabledelayedexpansion
set "file=example.txt"
for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
if exist "%%i:\" (
for /f "delims=" %%j in ('dir /s /b "%%i:\%file%"') do (
set "filepath=%%j"
del "!filepath!"
echo !filepath! deleted
)
)
)
echo All instances of %file% have been deleted.
pause
endlocal

Lower and remove special character of file name

I want to create a script, which lower and remove special character multiple text files.
my files in folder like this:
- ⚡ Document.txt
- [Review] Test File.txt
i want remove special char of filename like this
- document.txt
- review test file.txt
i've tried like this, but only lower filename. how to remove special character?
#echo off
setlocal enableDelayedExpansion
pushd %currentfolder%
for %%f in (*) do (
set "filename=%%~f"
for %%A in (a b c d e f g h i j k l m n o p q r s t u w x y z) do (
set "filename=!filename:%%A=%%A!"
)
ren "%%f" "!filename!" >nul 2>&1
)
endlocal
Before
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=u:\your files"
set "validchars=abcdefghijklmnopqrstuvwxyz1234567890. "
pushd "%sourcedir%"
FOR %%b IN (*) DO (
set "newname="
set "oldname=%%b"
call :validate
if /i "%%b" neq "!newname!" ren "%%~sb" "!newname!"
)
popd
GOTO :EOF
:validate
if not defined oldname goto :eof
set "c1=%oldname:~0,1%"
set "oldname=%oldname:~1%"
if "!validchars:%c1%=!" neq "%validchars%" set "newname=%newname%%c1%"
goto validate
Always verify against a test directory before applying to real data.
I predict it will have problems with some unicode characters and the usual suspects.
You could use pure powershell for this, or if you feel like continuing the use batch-file, just call powershell to assist:
#echo off
for %%i in (*) do for /f "delims=" %%a in ('powershell "$string='%%~ni';$String.tolower() -replace '[\W]', ''"') do echo ren "%%~i" "%%a%%~xi"
Note the echo at the end of the line, that is to test functionality by printing to screen before you do the actual renaming. Only remove echo when you're happy with the printed results.

How to mass rename files in a directory based on comparing file names in other directories sorted by size

I am attempting to make a batch script to rename a list of files based on matching names in another directory. My thought process for this goes something like this:
Things of Note
Files in directory 1 and 2 have the same names
Files in directory 2 and 3 have the same file size
Currently the script appears to do nothing and the files are unchanged
Loop through all files in directory 3 and assign to an array by size
Loop through all files in directory 2 and assign to an array by size
Compare names in directory 1 to directory 2 and rename matching files to that of directory 3
Here is what I was able to come up with (I am quite unfamiliar with batch so forgive me):
#Echo off
setlocal enableextensions enabledelayedexpansion
set /a i = 0
set /a j = 0
set /a k = 0
set /a l = 0
for /f "delims=" %%f in ('dir "PATHtoDirectory3*extension" /o:s /b') do (
set d3[%i%] = %%f
set /a i += 1
)
for /f "delims=" %%g in ('dir "PATHtoDirectory2*extension" /o:s /b') do (
set d2[%j%] = %%g
set /a j += 1
)
for /f "delims=" %%h in ('dir "PATHtoDirectory1*extension" /o:s /b') do (
set d1[%l%] = %%h
for /l %%x in (1,1,100) do (
if !d1[%l%]! == !d2[%k%]! (ren !d1[%l%]! !d3[%k%]!) else (set /a k += 1)
)
set /a l += 1
)
endlocal
An example would have been good.
Suppose we have (file name size) in each of the 3 directories:
dir1 dir2 dir3
c 1 b 6 w 6
d 2 c 7 x 7
a 3 a 8 y 8
b 4 d 9 z 9
I gather the quest is to rename c to x, d,z a,y b,w in dir1.
So - to your code (please use descriptive names - one-letter names are difficult to follow and may become confused with metavariables like %%x in your code)
for /f "delims=" %%f in ('dir "PATHtoDirectory3*extension" /o:s /b /a-d') do (
set /a i += 1
set "d3[!i!]=%%f"
)
Add the /a-d switch to prevent dir from reporting directorynames ("good practice", even if you are sure (at the moment) there'll be no subdirectories)
Increment the index, then store the data. This means you are dealing with d3[1..count] instead of d3[0..count-1]. This will make life easier.
Remove the spaces around the = as those spaces will be assigned to both the variable-name and the value stored in a string-assignment. "Quote the statement" to ensure that any stray trailing spaces on the line are assigned to the value.
You need the modified value of the index; !var! is the modified value, %var% is the value as it was when the statement was encountered (ie. parse-time)
Repeat for all 3 loops.
note that i, j and l should now each contain the number of filenames encountered. Presumably, these should be identical.
Next problem is that if the filename in d3 is identical to any filename in d1, then you could be attempting to rename d1\xyz to abc when d1\abc already exists.
Move the %%x loop from where it is to after the d1 array has been built.
Note that you have the count of names in i, j and l, so you can use
for /L %%x in (1,1,%i%) do ...
to iterate across the array, you don't need to use an arbitrary number. You can nest for statements :
for /L %%x in (1,1,%i%) do for /L %%y in (1,1,%i%) do ...
and now you can simply compare the d1,d2 names using
if "d1[%%x]"=="d2[%%y]"
and if this is true then d3[%%y] contains the new name.
To implement this, try
pushd PATHtoDirectory1
md tempdirname
for /L %%x in (1,1,%i%) do for /L %%y in (1,1,%i%) do if "d1[%%x]"=="d2[%%y]" (
move d1[%%x] .\tempname\d3[%%y]
)
move .\tempdirname\* .
rd tempdirname
popd
Where the pushd switches the current directory to PATHtoDirectory1; create a temporary directory there;match each name and move the file to the new name in the subdirectory;move the files with their new names back to the main directory;remove the subdirectory and popd returns to the original directory from which the batch is run.
Since the names in dir3 are unique, so the subdirectory will have unique names, and the rename to same or existing name problem is eliminated.

BATCH FOR-loop but start with specific file

I have a number of folders in Windows 10, each of which contains a number of PDF files. For each folder I need to run GhostScript with the folder's PDF files as input but with a certain file as the first one.
Each folder contains a file named, say, "FirstFile-X.pdf", where X can be anything, and for each folder I need that file to be the first input.
I have the following in a batch file:
setlocal enableDelayedExpansion
set gs="C:\Program Files\gs\gs9.54.0\bin\gswin64.exe"
set options=-dNOPAUSE -q -dBATCH -sDEVICE=pdfwrite
%gs% -sDEFAULTPAPERSIZE=a4 -dBATCH
for /d %%d in (*) do (
set a=
set output=%%d.pdf
for %%f in (%%d\*.pdf) do (
set "a=!a!%%d^\%%~nxf "
)
%gs% %options% -sOutputFile=!output! !a!
)
The above code works but it doesn't take that specific file as the first input. Is it possible to have the innermost for-loop run through each file in the order that I need?
The answer given by #aschipfl inspired me to do a different solution:
#echo off
setlocal enableDelayedExpansion
set "gs=C:\Program Files\gs\gs9.54.0\bin\gswin64.exe"
set "options=-dNOPAUSE -q -dBATCH -sDEVICE=pdfwrite"
"%gs%" -sDEFAULTPAPERSIZE=a4 -dBATCH
for /d %%d in (*) do (
set a=
for %%f in (%%d\*.pdf) do (
set string=%%~nf
if "!string:~0,5!"=="First" (
set "a=%%f !a!"
) else (
set "a=!a!%%f "
)
)
"%gs%" %options% -sOutputFile=%%d.pdf !a!
)
endlocal
I simply add the filename to the beginning of the string a, if the filename starts with "First", and if not the filename is added to the end of the string a. I also implemented some of the other small changes that #aschipfl suggested.
You could use an extra for loop that just iterates over the first file matching the pattern FirstFile-*.pdf (where only one match is expected). This file could be excluded in the other already present for loop. See the explanatory rem comments in the code:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
rem // Use quoted `set` syntax to assign unquoted values but still protect special characters:
set "gs=C:\Program Files\gs\gs9.54.0\bin\gswin64.exe"
set "options=-dNOPAUSE -q -dBATCH -sDEVICE=pdfwrite"
rem // Use quotation during expansion of variables:
"%gs%" -sDEFAULTPAPERSIZE=a4 -dBATCH
for /D %%d in (*) do (
set "a="
rem // Let an extra loop find the first file:
for %%e in ("%%d\FirstFile-*.pdf") do (
rem /* This condition is just necessary in case more than one files are found
rem by the extra loop in order to avoid duplicates in the returned list: */
if not defined a (
rem // Append the first file:
set "a=!a!%%~e "
rem // Iterate over all files (including first file):
for %%f in ("%%d\*.pdf") do (
rem // Exclude already processed first file at this point:
if /I not "%%~NXf"=="%%~NXe" set "a=!a!%%~f "
)
)
)
rem // There is no variable `output` needed:
"%gs%" %options% -sOutputFile=%%d !a!
)
endlocal
exit /B
Moreover, I made some other minor improvements, which are also commented in the code.
Note, that this code will still have troubles with directory and PDF file paths containing spaces and with such containing the characters ! and ^. To overcome them, you will need further quotation and toggling of delayed expansion:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Use quoted `set` syntax to assign unquoted values but still protect special characters:
set "gs=C:\Program Files\gs\gs9.54.0\bin\gswin64.exe"
set "options=-dNOPAUSE -q -dBATCH -sDEVICE=pdfwrite"
rem // Use quotation during expansion of variables:
"%gs%" -sDEFAULTPAPERSIZE=a4 -dBATCH
for /D %%d in (*) do (
set "a="
set "output=%%d"
rem // Let an extra loop find the first file:
for %%e in ("%%d\FirstFile-*.pdf") do (
rem // Store currently iterated item:
set "item=%%~e"
rem /* This condition is just necessary in case more than one files are found
rem by the extra loop in order to avoid duplicates in the returned list: */
if not defined a (
rem // Toggle delayed expansion to avoid issues with `!` and `^`:
setlocal EnableDelayedExpansion
rem // Append the first file in a quoted manner:
set "a=!a!"!item!" "
rem // Transfer value `a` over `endlocal` barrier:
for /F "delims=" %%t in ("a=!a!") do endlocal & set "%%t"
rem // Iterate over all files (including first file):
for %%f in ("%%d\*.pdf") do (
rem // Store currently iterated item:
set "item=%%~f"
rem // Exclude already processed first file at this point:
if /I not "%%~NXf"=="%%~NXe" (
rem // Toggle delayed expansion to avoid issues with `!` and `^`:
setlocal EnableDelayedExpansion
rem // Append the current item in a quoted manner:
set "a=!a!"!item!" "
rem // Transfer value `a` over `endlocal` barrier:
for /F "delims=" %%t in ("a=!a!") do endlocal & set "%%t"
)
)
)
)
rem // Eventually use delayed expansion as well as quotation:
setlocal EnableDelayedExpansion
"!gs!" !options! -sOutputFile="!output!" !a!
endlocal
)
endlocal
exit /B

recursively rename files AND subfolders in a folder using batch script

I know there are similar posts, but non covers what I need.
I need to rename all the files and sub folders of a given folder and make them uppercase. I found this post which is great but only does the files OR subfolders:
Rename all files in folder to uppercase with batch
I tried doing nested FOR with no joy. According to the manual, /R is suppose to recur through folders, but it is not doing anything. Tried /D /R with no luck either. So I was hoping to use something like below:
#echo off
setlocal enableDelayedExpansion
pushd C:\MyFolder
for /R /D %%f in (*) do (
set "filename=%%~f"
for %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
set "filename=!filename:%%A=%%A!"
)
ren "%%f" "!filename!" >nul 2>&1
)
endlocal
Any ideas?
Parse a static list dir /B /S * to get all files and subfolders.
Read entire for /? for %%~nxf explanation.
#echo off
setlocal enableDelayedExpansion
pushd C:\MyFolder
for /F "delims=" %%f in ('dir /B /S *') do (
set "filename=%%~nxf"
for %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
set "filename=!filename:%%A=%%A!"
)
ren "%%~f" "!filename!" >nul 2>&1
)
popd
endlocal
Read ren /? as well:
Renames a file or files.
RENAME [drive:][path]filename1 filename2.
REN [drive:][path]filename1 filename2.
Note that you cannot specify a new drive or path for your destination file.

Resources