I created a Menu to call this script that renames multiple text files randomly, it is only working in a .bat file alone. But it is not working in the context of the menu I created, I believe it's something to do with looping, since it only renames the first file! I would like someone to evaluate the situation, thank you very much already.
:4
cls
setlocal disableDelayedExpansion
set "chars=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for /f "eol=: delims=" %%F in ('dir /b /a-d *.txt') do call :renameFile "%%F"
exit /b
:renameFile
setlocal enableDelayedExpansion
:retry
set "name="
for /l %%N in (1 1 8) do (
set /a I=!random!%%36
for %%I in (!I!) do set "name=!name!!chars:~%%I,1!"
)
echo if exist !name!.txt goto :retry
endlocal & ren %1 %name%.txt
)
pause
goto Menu
)
:5 < - here start the next option of menu
...
Perhaps like this:
:4
cls
setlocal disableDelayedExpansion
set "chars=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for /f "eol=: delims=" %%F in ('dir /b /a-d *.txt') do call :renameFile "%%F"
pause
goto Menu
:renameFile
setlocal enableDelayedExpansion
:retry
set "name="
for /l %%N in (1 1 8) do (
set /a I=!random!%%36
for %%I in (!I!) do set "name=!name!!chars:~%%I,1!"
)
if exist !name!.txt goto :retry
endlocal & ren %1 %name%.txt
goto :eof
The echo on the exist line is curious. Seems like the ren could error without that.
After reviewing better I see that exit /b is the command that makes the window close after goto: eof it returns to the commands from above. So, i replace exit /b section per:
pause
goto Menu
and now it return to my Menu
:Menu
Complete Code:
cls
setlocal disableDelayedExpansion
set "chars=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for /f "eol=: delims=" %%F in ('dir /b /a-d *.txt') do call :renameFile "%%F"
pause
goto Menu
:renameFile
setlocal enableDelayedExpansion
:retry
set "name="
for /l %%N in (1 1 8) do (
set /a I=!random!%%36
for %%I in (!I!) do set "name=!name!!chars:~%%I,1!"
)
if exist !name!.txt goto :retry
endlocal & ren %1 %name%.txt
goto :eof
Related
I'm trying to grab a couple of lines in some files and store them in variables (line3 and line4).
Here is the code:
setlocal EnableDelayedExpansion
for /f "tokens=*" %%a in ('dir *.md /b /o:-n /a:-d') do (
call :getLines "%%a"
)
pause
exit
:getLines
set /A cnt=2
for /f "skip=4 tokens=*" %%b in (%1) do (
set /A cnt+=1
set "line!cnt!=%%b"
if !cnt! == 4 (
set "filename=%~n1"
set "blogdate=!filename:~0,10!"
set "blogtitle=!filename:~11!"
echo hello
echo !line3!
echo !line4!
echo !filename!
echo !blogdate!
echo !blogtitle!
)
)
goto :eof
The above will not even echo hello. I can't see what's wrong.
This is what each file looks like:
# Title
*2015-11-17*
Tags: word1 word2
First Sentence is here.
Filenames look like this:
2015-11-17-title.md
You passed to call with quotes, so you should strip it first (or use usebackq).
Also when you are testing, don't use exit yet.
Try this, see if it works:
(Formatted so the structure is more clear, try comment #echo off to get more details.)
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%a in ('dir *.md /b /o:-n /a:-d') do (
call :getLines "%%a"
)
pause
::exit
goto :eof
:getLines
set /A cnt=2
for /f "usebackq skip=4 tokens=*" %%b in (%1) do (
set /A cnt+=1
set "line!cnt!=%%b"
if !cnt! == 4 (
set "filename=%~n1"
set "blogdate=!filename:~0,10!"
set "blogtitle=!filename:~11!"
echo hello
echo !line3!
echo !line4!
echo !filename!
echo !blogdate!
echo !blogtitle!
goto :eof
)
)
goto :eof
for will take the input with quotes as string not as file.
%~1 will strip %1's quotes.
Check for /? and call /? for more details.
What I am trying to do is replace part of a file name with my computer name.
#echo off
set host=%COMPUTERNAME%
set host=%host:~4, -2%
for /f "delims=" %%a in ('dir /a:-d /o:n /b') do call :next "%%a"
pause
GOTO:EOF
:next
set "newname=%~nx1"
set "newname=%newname:XXXX=zzzz%"
echo ren %1 "%newname%
When I run the above, it replaces the XXXX's with zzzz's
When I change set "newname=%newname:XXXX=zzzz%" to set "newname=%newname:XXXX=%host%"it just deletes the X's.
What happens if you use delayed expansion?
#Echo Off
SetLocal EnableDelayedExpansion
Set "Host=%COMPUTERNAME:~4,2%"
For /F "Delims=" %%A In ('Dir /B/A-D/ON') Do (Set "NewName=%%~nA"
Echo Ren "%%~A" "!NewName:XXXX=%Host%!%%~xA"
Pause
GoTo :EOF
I have a text file with a list of server IP addresses and the code below (which I've scrapped together from other coding) loops through it and brings back a modified date of a named file for each server in the list...
#ECHO On
SETLOCAL
FOR /f %%a IN (C:\Scripts\Servers.txt) DO (
CALL :getmod %%a
)
GOTO :EOF
:getmod
SET Server=%1
SET File=Abs_Client.exe
FOR %%i IN ("\\%Server%\C$\Com_Dir\%File%") DO SET modif_time=%%~ti
Echo %Server% %File% %modif_time% >> "C:\Scripts\Server_App_Mod_date.txt"
GOTO :eof
That works great...however, what I'd like to do is create another loop around it which creates a variable for each file in a directory and pass that into the code above instead of having to manually change the 'SET File' as shown above for individual files.
Something along the lines of;
#ECHO On
SETLOCAL
FOR /D %VAR IN ("\\Network_Location\AppMedia\App Source Files\Prod Apps\Server_Update") DO (
FOR /f %%a IN (C:\Scripts\Servers.txt) DO (
CALL :getmod %%a
)
GOTO :EOF
:getmod
SET Server=%1
SET File=%VAR
FOR %%i IN ("\\%Server%\C$\Com_Dir\%File%") DO SET modif_time=%%~ti
Echo %Server% %File% %modif_time% >> "C:\Scripts\Server_App_Mod_date.txt"
GOTO :eof
)
Clearly it's wrong so any ideas/help please?
haven't testet, but maybe a hint in the right direction:
#ECHO ON
SETLOCAL
FOR /F "TOKENS=*" %%F IN ('DIR "\\Network_Location\AppMedia\App Source Files\Prod Apps\Server_Update" /s /b /a:-d') DO (
FOR /F %%A IN (C:\Scripts\Servers.txt) DO (
CALL :getmod %%A "%%~nxF"
)
)
GOTO :EOF
:getmod
SET Server=%1
SET "tmpFile=%~2"
FOR %%I IN ("\\%Server%\C$\Com_Dir\%tmpFile%") DO ECHO %Server% %tmpFile% %%~tI >> "C:\Scripts\Server_App_Mod_date.txt"
GOTO :EOF
As far as i know, FOR /D only executes for directorys and if i understand your question, you have files in "Prod Apps\Server_Update", for each you like to have the file-date/time from the target-server... right?
Edit:
Maybe this works too:
FOR /F "TOKENS=*" %%F IN ('DIR "\\Network_Location\AppMedia\App Source Files\Prod Apps\Server_Update" /s /b /a:-d') DO (
FOR /F %%A IN (C:\Scripts\Servers.txt) DO (
FOR %%X IN ("\\%%A\C$\Com_Dir\%%~nxF") DO ECHO %%A %%~nxF %%~tX >> "C:\Scripts\Server_App_Mod_date.txt"
)
)
without the :getmod
Edit: /b-switch was missing from the first DIR-Command in 2nd suggestion
#ECHO On
SETLOCAL
FOR /f %%a IN (C:\Scripts\Servers.txt) DO (
FOR /f "delims=" %%i IN ('dir /b/a-d "\\%%a\C$\Com_Dir\*"') DO Echo %%a %%i %%~ti >> "C:\Scripts\Server_App_Mod_date.txt"
)
GOTO :EOF
Should work, IIUC. Can't test, I'm afraid...
[Edit - removed call to getmod - not required]
Need your help
I need create a batch file (command prompt) to
⁃ Show a list of folders and sub folders
⁃ within them are exe files
⁃ Only show the 2 most up to date exe files
⁃ display specific folders not all
And export information in a txt file
I'm using XP if that helps
update
I have the below commands
first one works and orders by most recent file, but doesn't give me time and date
second shows time and date but doesn't order by most recent
#ECHO OFF
setlocal EnableDelayedExpansion
set j=0
Echo Test
echo\
FOR /f "delims=" %%i IN ('dir C:\test\ /o-n-d /b') DO (
echo %%i
set /A j=j+1
if !j! geq 2 (
goto :end1
)
)
:end1
#ECHO OFF
setlocal EnableDelayedExpansion
set j=0
echo\
Echo Test
echo\
FOR /f "delims=" %%i IN ('forfiles /p C:\testmove /s /m *.* /C "cmd /c echo #file #fdate #ftime" ') DO (
echo %%i
set /A j=j+1
if !j! geq 2 (
goto :end2
)
)
:end2
pause
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
SET "lastdir="
(
FOR /f "delims=" %%a IN (
'dir /s /b /a-d "%sourcedir%\*.exe" '
) DO (
IF "%%~dpa" neq "!lastdir!" (
SET "lastdir=%%~dpa"
SET /a count=0
FOR /f "delims=" %%i IN ('dir /s /b /a-d /o:d "%%~dpa\*.exe"') DO IF !count! lss 2 (
SET /a count+=1
ECHO %%~ti %%~fi
)
)
)
)>newfile.txt
GOTO :EOF
Produces newfile.txt. You would need to set your required directory name in sourcedir. I showed the data as date/time fullfilename because fullfilename is of variable-length whereas date and time are fixed. Might have been easier if you'd shown us the format you expect - saves guesswork and revisions.
To show the two most recently modified files, change .../b /a-d /o:d "%%~... to .../b /a-d /o:-d "%%~... (note - between the o: and d)
Uses Robocopy to show the two latest modified .exe files in the current folder tree
It also displays the UTC date and time of the two files.
#echo off
setlocal enabledelayedexpansion
set "folder=%cd%"
set c=0
for /f "tokens=1,2,*" %%a in (
'robocopy "%folder%" "%folder%" "*.exe" /s /is /nocopy /nc /ns /ts /fp /np /ndl /njh /njs /xjd /r:0 /w:0 /l ^| sort /r '
) do echo "%%a %%b" - "%%c" & set /a c+=1 & if !c! EQU 2 goto :done
:done
pause
set dSource=C:\Games\Steam\steamapps
set dTarget=E:\Demos
set fType=*.dem
xcopy/i "%dSource%\%fType%" "%dTarget%"
This is what I currently have to copy all my files, but how can I get it to copy all the files and rename any that have the same name, so that both copies are kept in the destination folder.
Eg:source:demo.dem
destination:demo.dem
Goes to:
destination:demo.dem, demo(1).dem
Try this solution with copy:
#echo off &setlocal
set "dSource=C:\Games\Steam\steamapps"
set "dTarget=E:\Demos"
set "fType=*.dem"
for %%i in ("%dSource%\%fType%") do if not exist "%dtarget%\%%~nxi" (copy /b "%%~i" "%dtarget%") else call :process "%%~i"
goto :eof
:process
set /a cnt=-1
:loop
set /a cnt+=1
set "fname=%dtarget%\%~n1(%cnt%)%~x1"
if exist "%fname%" goto :loop
copy /b "%~1" "%fname%"
goto :eof
endlocal
#ECHO OFF
SETLOCAL
SET source=c:\sourcedir
SET dest=c:\destdir
SET mask=*.*
FOR /f "delims=" %%i IN (
' dir /b /a-d "%source%\%mask%" '
) DO IF EXIST "%dest%\%%i" (
SET "destfn="
SET "sourcefn=%source%\%%i"
FOR /l %%g IN (1,1,9) DO IF NOT DEFINED destfn IF NOT EXIST "%dest%\%%~ni(%%g)%%~xi" SET destfn=%dest%\%%~ni(%%g^)%%~xi
IF NOT DEFINED destfn FOR /l %%g IN (10,1,99) DO IF NOT DEFINED destfn IF NOT EXIST "%dest%\%%~ni(%%g)%%~xi" SET destfn=%dest%\%%~ni(%%g^)%%~xi
IF NOT DEFINED destfn FOR /l %%g IN (100,1,999) DO IF NOT DEFINED destfn IF NOT EXIST "%dest%\%%~ni(%%g)%%~xi" SET destfn=%dest%\%%~ni(%%g^)%%~xi
IF NOT DEFINED destfn FOR /l %%g IN (1000,1,9999) DO IF NOT DEFINED destfn IF NOT EXIST "%dest%\%%~ni(%%g)%%~xi" SET destfn=%dest%\%%~ni(%%g^)%%~xi
CALL :copyg
) ELSE (XCOPY "%source%\%%i" "%dest%\" >nul)
)
GOTO :eof
:copyg
IF DEFINED destfn (ECHO F|XCOPY "%sourcefn%" "%destfn%" >nul
) ELSE (ECHO "%sourcefn%" NOT copied - out of generation numbers
)
GOTO :eof
WARNING: As posted, the procedure will XCOPY.
I'd suggest you change the XCOPY statements to ECHO... and >nul / ECHO F| to examine what XCOPY instructions would be generated first.
(the >nul suppresses copied messages; the ECHO F| forces XCOPY to copy to a destination FILE since there's no XCOPY switch to allow this)