Thanks to rojo the batch file below will check for illegal characters, replace them with a dash, search subdirectories and require a location argument, but when it's run it takes you to the directory you specify in the argument. I want to stay in drive/folder the batch file is run from. (ex: rename.bat c:\test, this will take you to c:\test after batch file runs)
##echo off
IF "%~1"=="" goto Continue
pushd %1
setlocal enabledelayedexpansion
for /r %%I in (*) do (
set "file=%%~nxI"
if "!file:~0,1!"=="~" (
set "file=-!file:~1!"
)
for %%d in (# %%) do (
if not "!file!"=="!file:%%d=!" (
set "file=!file:%%d=-!"
)
)
if not "!file!"=="%%~nxI" (
echo %%~fI -^> !file!
ren "%%~fI" "!file!"
)
)
Exit /B
:Continue
#echo You need drive and directory at end or this batch file
At the end of your FOR /R loop, add POPD to "undo" the directory change performed by the respective PUSHD command.
setlocal enabledelayedexpansion
pushd %1
for /r %%I in (*) do (
...
)
REM Revert back to the original directory.
POPD
ENDLOCAL
Exit /B
:Continue
Related
I already have a batch file that I can drop in any SHOW_NAME directory and it will move files from a sub-folder to its SEASON parent directory. For example:
F:\TV_SHOWS\SHOW_NAME\SEASON1\TITLE_EP1\title_episode1.mkv
F:\TV_SHOWS\SHOW_NAME\SEASON1\TITLE_EP2\title_episode2.mkv
F:\TV_SHOWS\SHOW_NAME\SEASON1\TITLE_EP3\title_episode3.mkv
F:\TV_SHOWS\SHOW_NAME\SEASON1\title_episode3.mkv
When it moves all files to the parent folder (SEASON1) the "title_episode3.mkv" is a duplicate and overwrites the original. How can I automatically rename by appending a number "title_episode3 (1).mkv"?
Here is the code that I use in a batch file:
#echo off
for /d /r %%f in (*) do (
for /d %%g in ("%%f\*") do (
for %%h in ("%%~g\*.mkv") do move "%%~h" "%%~f" >nul 2>&1
)
)
Thanks!
This commented batch file can be used for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Search for any file two directory levels below specified directory
rem and pass to subroutine MoveFile the name of the file with full path.
for /D %%A in ("F:\TV_SHOWS\SHOW_NAME\*") do (
for /D %%B in ("%%A\*") do (
for /F "delims=" %%I in ('dir "%%B\*" /A-D /B /S 2^>nul') do call :MoveFile "%%I"
)
)
endlocal
goto :EOF
:MoveFile
set "FilePath=%~dp1"
set "FileNameOnly=%~n1"
set "FileNameFull=%~1"
set "FileName+Ext=%~nx1"
set "FileExtension=%~x1"
rem For files staring with a dot and not containing one more dot.
if "%FileNameOnly%" == "" set "FileNameOnly=%~x1" & set "FileExtension="
rem Get path to parent folder ending with a backslash.
for /F "delims=" %%J in ("%FilePath:~0,-1%") do set "FileParent=%%~dpJ"
rem Uncomment the line below to see the values of the six File* variables.
rem set File & echo/
rem Does a file with current file name not exist in parent folder?
if not exist "%FileParent%%FileName+Ext%" (
rem Move the file to parent folder and if this was successful
rem delete the folder of the moved file if being empty now.
move "%FileNameFull%" "%FileParent%%FileName+Ext%" >nul
if not errorlevel 1 rd "%FilePath%" 2>nul
goto :EOF
)
set "FileNumber=1"
:NextFile
if exist "%FileParent%%FileNameOnly% (%FileNumber%)%FileExtension%" set /A "FileNumber+=1" & goto NextFile
move "%FileNameFull%" "%FileParent%%FileNameOnly% (%FileNumber%)%FileExtension%" >nul
if not errorlevel 1 rd "%FilePath%" 2>nul
goto :EOF
Running the batch file a second time on same directory with no new subdirectory and no new file does not change anything.
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.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
move /?
rd /?
rem /?
set /?
setlocal /?
See also:
the Microsoft article about Using Command Redirection Operators;
Single line with multiple commands using Windows batch file;
Where does GOTO :EOF return to?
This batch code is to search all the PDF files in the path specified by the user and copy them all in the home folder and then deleting everything that is inside that folder (subfolders and files). How can I force my code to look for multiple files like pdf,txt and else.
#echo off
setlocal enabledelayedexpansion
goto :main
:main
setlocal
cls
echo.
echo Enter the home directory path where you want to apply the cleaning
set /p path=
echo %path%
cd %path%
for /d %%g in (*) do (
echo %%g
cd %%g
for /r %%p in (*.pdf) do (
set dest=!cd!
set app=/
copy %%p !%dest%%app%!
echo %%p
echo !cd!
)
for /d %%z in (*) do (
rmdir %%z /s /q
)
cd ..
)
pause
endlocal
goto :eof
Nothing prevents you from doing
for /r %%p in ( *.jpg *.png ) do (
REM do something with %%p
)
The catch is that you can use any number of extensions separated by space withing parenthesis.
Is there a way to check if a new folder (exact name is unknown) has been created inside a specific parent folder as a result of running previous commands in bat file? If yes - run one more command with the full path to a new folder as an argument to that command.
Right now I am using a folder monitoring software to run another bat if new folder is created. I would like to have just one script performing both tasks.
Thank you for your help.
change the root_folder location on the second line
#echo off
set "root_folder=C:\something"
setlocal enableDelayedExpansion
set counter=1
for /d /r "%root_folder%" %%a in (*) do (
set "dirs[!counter!]=%%~sa" >nul
set /a counter=counter+1
)
rem ############################
rem # call your code here !!! #
rem ############################
call commands.bat
rem for /l %%l in (1,1,!counter!) do (
rem dir /x /b /s /a:d "%root_folder%" | findstr /i "dirs[%%l]"
rem )
set flag=0
for /d /r "%root_folder%" %%a in (*) do (
set dirs[|find /i "%%~sa" >nul 2>nul ||(
echo "%%~sa" is a new folder
set flag=1
)
)
if %flag% equ 0 (
echo no new folders
)
The objective is to display the directory name in MYFOLDER.
MY.exe exists in the folder, but curiously, without the wildcard in ...\desktemp*, the "#echo Showing subfolders" is never displayed, but "#echo G is working" is. However MY.exe is never found when moved to one of the subfolders.
OTOH the current code never finds MY.exe and never displays "#echo G is working" but properly lists each subfolder: "#echo Showing subfolders".
The other problem is the pauses at the end of the block are never reached.
Substituting the inner For with
cd \Users\%USERNAME%\Desktop
for /D /r %%G in ("desktemp*") do (
gets essentially the same result. My.exe isn't found if moved to one of the subfolders of desktemp.
Setlocal EnableDelayedExpansion
set CURRDRIVE=C
SET MYFOLDER=
:SEARCHDRIVES
REM BLOCK
for %%B in (C) do (
if exist %%B: (
PUSHD %%B:\
if NOT DEFINED MYFOLDER (
ECHO "%CD%"
REM This always displays path batch is run from.
REM The above Pushd doesn't change to C:\
for /f "tokens=*" %%G in ('dir /b /s /a:d "%%B:\Users\%USERNAME%\Desktop\desktemp*" ^| find "\"') do (
#echo Showing subfolders
#echo %%G
pause
if exist "%%G\MY.exe" (
call set MYFOLDER=%%G
#echo %%G
#echo G is working
call echo %MYFOLDER%
pause
GOTO GOTMYFOLDER
)
)
)
)
REM Exist Drive
)
REM Drives Loop
:GOTMYFOLDER
cd /d %CURRDRIVE%:\
echo %MYFOLDER%
cd %MYFOLDER%
pause
The above is a chunk whittled from a larger code block: the ultimate aim will be to get the folder names"\Users\New\Desktop\desktemp" into a variable via prompt.
Are the Escape Characters, Delimiters and Quotes in the nested blocks implemented properly?
The answer escaped this poor little brain until it cottoned on to what the "DIR" and "For /D /R" were really up to. What was sought for was in the addition of a new "For /D" (no /R).
This first (extra) "For /D" determines the folder names to iterate from.
(Specifically anything but the Windows directory where we run into problems with >260 filenames.)
This locates the MY.exe file somewhere in the Users folder (more precisely in any root folder beginning with U):
Setlocal EnableDelayedExpansion
set CURRDRIVE=C
SET MYFOLDER=
:SEARCHDRIVES
REM BLOCK
for %%B in (C) do (
if exist %%B: (
PUSHD %%B:\
if NOT DEFINED MYFOLDER (
ECHO "%CD%"
REM This always displays path batch is run from.
REM The above Pushd doesn't change to C:\
for /D %%Z in (U*) do (
cd \%%Z
for /D /r %%G in ("*") do (
if exist "%%G\MY.exe" (
call set MYFOLDER=%%G
#echo %%G
#echo G is working
call echo %MYFOLDER%
pause
GOTO GOTMYFOLDER
)
)
)
)
)
REM Exist Drive
)
REM Drives Loop
:GOTMYFOLDER
cd /d %CURRDRIVE%:\
echo %MYFOLDER%
cd %MYFOLDER%
pause
Edit:
The source of the error spam in the comment below is this command:
Insert batch code to elevate UAC privileges [code][1] from TanisDL
Setlocal EnableDelayedExpansion & pushd "%CD%" & CD /D "%~dp0"
set CURRDRIVE=C
FOR /F "usebackq delims==" %%G IN (dir %CURRDRIVE%:\ /A:D /O:G /S /B ^| FIND /I "myString") DO (set "foundMyString=%%~pG")
This is not working.. No errors.
Have directories:
123.abc
123.def
123.ghi
Want to rename to:
abc
def
ghi
What I have done is not working..
I have used: http://www.dostips.com/DtTipsStringOperations.php
Renaming Folder Structure in Batch
SETLOCAL ENABLEDELAYEDEXPANSION
for /d %%D in ("C:\batch\*") do CALL :RENAME %%D %%~nxD
:RENAME
set "folder=%%~nxD"
rem https://stackoverflow.com/questions/11040473/batch-file-string-character-split
set "x=%folder:~-3%"
FOR /D %%R IN (%1%) DO RENAME %%R "%x%"
ENDLOCAL
pause
#echo off
rem Prepare environment
setlocal enableextensions enabledelayedexpansion
rem For each directory under selected folder
for /d %%d in ("c:\batch\*") do (
rem Get the extension of the directory if any
set "name=%%~xd"
rem If there is a extension
if defined name (
rem Remove the dot from extension
set "name=!name:~1!"
rem If no file/folder exists with the new name, rename the dir
if not exist "%%~dpd\!name!" echo ren "%%~fd" "!name!"
)
)
endlocal
Final rename command is "echoed" to the console. If output is correct then remove the echo from ren command line.
This will rename the folders to the text after the first period.
Remove the echo to activate the command as currently it will only echo the commands to the console.
#echo off
for /f "tokens=1,* delims=." %%a in ('dir "C:\batch" /ad /b ') do echo REN "C:\batch\%%a.%%b" "%%b"
pause