I have scoured the site and have been able to extract code which virtually handles all that I am seeking to achieve. However, I cannot get the last bit to work which is to loop back to the start if I want to re-key another Sheet Number. The code I have:
#Echo Off
cd "C:\temp\CopiedTo"
del *.* /Q
CLS
:start
#Echo Off
Set /P SheetNo=Enter the Sheet Number to Copy:
if exist "C:\temp\%SheetNo%.txt" (Copy "c:\temp\%sheetNo%.txt" "c:\temp\copiedto"
) Else (Echo set choice=
set /p choice="This Sheet Number Is Currently Not in the Directory - Do you wish to Re-Key Again? Press 'y' and enter for Yes: "
if not '%choice%'=='' set choice=%choice:~0,1%
if '%choice%'=='y' goto start
)
You use the %choice% variable inside a block. So you need delayed expansion.
Put a
setlocal enabledelayedexpansion
at the beginning of your script and use !choice! instead of %choice% inside the block.
And: remove the echo before set choice= (probably there for testing)
Here is another way to do it, with a simpler interface.
Note that an automated del *.* on it's own is a dangerous command when the preceding cd command can fail and whatever directory is current can be nuked, so it's always best to specify the folder or do some extra testing to check if the CD failed.
The CD command now has the /d switch to cater for another drive being current.
#Echo Off
cd /d "C:\temp\CopiedTo"
del "C:\temp\CopiedTo\*.*" /Q
CLS
:start
#Echo Off
set "sheetno="
Set /P "SheetNo=Enter the Sheet Number to Copy (press enter to quit): "
if not defined sheetno goto :EOF
if exist "C:\temp\%SheetNo%.txt" (
echo copying "%sheetNo%.txt"
Copy "c:\temp\%sheetNo%.txt" "c:\temp copiedto" >nul
) Else (
echo "Sheet Number "%sheetNo%.txt" Is Currently Not in the Directory
)
goto :start
Related
I am currently trying to create a batch script so I can sort multiple tiff images in a folder by moving it to other specific folder according to user input. What I achieved so far is:
1. Can loop through all the files in the folder
2. Can open the image viewer to view the tiff file
3. Close off the image viewer program
4. Move the tiff file to specific folder
However, I do not know why my set /p is not registering user's input value, when I tried to echo the input out.
cmd gave me "ECHO is off" message.
Appreciate if anyone could give me a hand to resolve this problem.
Many thanks
G
#ECHO OFF
cd "C:\img\"
FOR /R %%f IN (*.tif) DO (
echo Current file is: %%f
start "" "C:\Program Files (x86)\Common Files\Global 360\Imaging\kodakprv.EXE" %%f
set /p name= Action:
IF "%name%" == "1" GOTO ONE
IF "%name%" == "2" GOTO TWO
IF "%name%" == "3" GOTO THREE
ECHO %name%
echo None of the above, BYE!
GOTO END
:ONE
echo "I pressed 1"
taskkill /IM kodakprv.EXE
move %%f "C:\img\1"
cls
:TWO
echo "I pressed 2"
taskkill /IM kodakprv.EXE
move %%f "C:\img\2"
cls
:THREE
echo "I pressed 3"
taskkill /IM kodakprv.EXE
move %%f "C:\img\3"
cls
)
:END
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
cd "C:\img\"
FOR /R %%f IN (*.tif) DO (
echo Current file is: %%f
start "" "C:\Program Files (x86)\Common Files\Global 360\Imaging\kodakprv.EXE" %%f
SET "name="
set /p name= Action:
for %%v in (1 2 3) do IF "!name!" == "%%v" (
set "validaction=Y"
echo "I pressed %%v"
taskkill /IM kodakprv.EXE
move %%f "C:\img\%%v"
pause
cls
)
if not defined validaction (
ECHO !name!
echo None of the above, BYE!
GOTO END
)
)
:END
A few little problems.
First, you can't use labels within a code block (parenthesised series of commands) and second the old favourite, delayedexpansion - if a variable is changed within a code block then unless delayed expansion is in effect, the original value will be used. If delayed expansion is in effect, then %var% refers to the original value and !var! to the current (run-time) value.
Note also that set /p does not change the value of the variable if user response is simply Enter - -hence the set "name=" above to clear its value. Of course, you can omit that line and the last-entered value of name will be used again if you just press Enter.
There are many articles on SO about delayed expansion - just use the search feature.
So, here's what I have: I created a small batch file to record the results of a ping test to a text file. What I want to do is run the batch file and move the results log to a specific folder on the Desktop automatically. Then, if the target filename exists, automatically rename accordingly. Meaning, if File1 exists, create File2, File3, so on and so forth. Here's what I have so far:
#echo off
color A
title Ping Test
:A
echo.
cls
ping google.com -n 4 > C:\Users\%username%\Desktop\pingresults.txt
cls
:Question
echo.
echo You can find the results in C:\Users\%username%\Desktop\pingresults.txt
echo Would you like to run this test again? (Y/N)
Set /p Choice=
if %choice% equ y goto :A
if %choice% equ n goto :Results
if %choice% neq y goto :Question
if %choice% neq n goto :Question
:Results
cls
echo Would you like to view the results of the test? (Y/N)
Set /p Choice=
if %choice% equ y goto :OpenResults
if %choice% equ n goto :Close
if %choice% neq y goto :Results
if %choice% neq n goto :Results
:Close
exit
:OpenResults
start C:\Users\%username%\Desktop\pingresults.txt
And the move batch file looks like this:
#echo off
echo.
cd C:\Users\Diesel\Desktop
move pingresults.txt PingResults\
if exist pingresults.txt ren pingresults.txt=+1
Exit.
I don't want to overwrite the existing file, but rename it in succession. I can't find any helpful articles anywhere using only batch files, they all say to use vbs or php, a language I'm not familiar with
To rename files to file1 [file2][...] and move it in a desktop folder:
#ECHO Off &SETLOCAL
FOR %%a IN (*.txt) DO CALL:processFile "%%~a"
goto:eof
:processFile
SETLOCAL
:loop
SET /a fileCounter+=1
SET "fileName=%~n1%filecounter%%~x1"
IF EXIST "C:\Users\%username%\Desktop\%fileName%" GOTO:loop
ECHO MOVE "%~1" "C:\Users\%username%\Desktop\%fileName%"
ENDLOCAL
goto:eof
Look at the output and remove the word echo before move if it looks good.
I have a pair of utility files that do this, so I can call from either command line, or another batch file. This manages several versions of the file in the same folder, and I would call it before moving your new file in.
Usage is:
archivefile 5 "c:\temp\songs" .txt [move]
Where 5 is the number of versions to keep.
The base file name in this example is "c:\temp\songs.txt"
and it creates (in c:\temp) 5 files: songs_1.txt songs_2.txt songs_3.txt songs_4.txt songs_5.txt
If you specify move it will move the original songs.txt otherwise it copies it.
Note, if you're using it from another batch file (which you'll probably want to), you need to use call or it won't return to your original batch file (both batch files will exit instead, which isn't what you want):
call archivefile 5 "c:\temp\songs" .txt
You need the pair of batch files to be either in the current directory, or on the windows path. Now I think about it, archivefile_b.bat could probably be a sub-routine within the main file instead, but it ain't broke, so I'm not going to fix it.
This is archivefile.bat:
#Echo off
rem archivefile.bat - keep a number of archives of a file
rem paramters: n rootfile extension [move|copy]
rem n = number of files to keep.
rem move|copy optional indicator to rename (move) the original file instead of copying it
rem archivefile 5 "c:\temp\songs" .txt [move]
rem
if "%3"=="" goto usage
set _af_n=%1
set _af_root=%2
set _af_ext=%3
set _af_move=copy
set _af_moveX=%4
if "%_af_moveX%"=="move" set _af_move=move
set _af_i=
set _af_j=
rem make sure that the first parameter (n) is numeric
set /A _af_n=%_af_n%
if "%_af_n%"=="0" echo Error: number of copies must be numeric (%1) & goto usage
if not exist %_af_root%%_af_ext% echo Error: cannot locate main file: %_af_root%%_af_ext% & goto error
rem remove the oldest file
if exist %_af_root%_%_af_n%%_af_ext% del %_af_root%_%_af_n%%_af_ext%
rem move up the remainder
for /L %%i in (%_af_n%, -1, 1) do call archivefile_b %%i %_af_root% %_af_ext%
rem copy the original
if "%_af_move%"=="move" goto moveIt
rem move not specified - make a copy
copy %_af_root%%_af_ext% %_af_root%_1%_af_ext%
goto moveCopyDone
:moveIt
rem need filename only for a rename
set _af_destfile=%_af_root%_1%_af_ext%
set _af_destfile=%_af_destfile:"=%
for %%i in (%_af_destfile%) do set _af_destfile=%%~ni%%~xi
ren %_af_root%%_af_ext% %_af_destfile%
:moveCopyDone
dir %_af_root%*%_af_ext%
goto done
:usage
echo usage: archivefile n rootfile extension
echo - n = number of archives to keep
echo - rootfile = the root filename
echo - extension = file extension
echo.
echo example:
echo archivefile 5 "c:\Documents and Settings\gregh\My Documents\Rescued document" .txt
goto done
:error
rem could maybe do something here? naa.
goto done
:done
This is archivefile_b.bat, which manages just one of the files:
rem #Echo off
rem archivefile_b.bat - helper for the archivefile routine
rem -- juggles ONE of the archive files.
rem paramters: n rootfile extension
rem n = the index to move from n to n+1
rem archivefile 5 "c:\temp\songs" .txt
rem therefore renames c:\temp\songs_5.txt to c:\temp\songs_6.txt
set _afb_n=%1
set _afb_root=%2
set _afb_ext=%3
rem make sure that the first parameter (n) is numeric
set /A _afb_n=%_afb_n%
if "%_afb_n%"=="0" echo Error: (archivefile_b) number of copies must be numeric (%1) & goto done
set /A _afb_j=%_afb_n%+1
rem define the file names
set _afb_fn=%_afb_root%_%_afb_n%%_afb_ext%
set _afb_fj=%_afb_root%_%_afb_j%%_afb_ext%
rem remove the quotes
set _afb_fn=%_afb_fn:"=%
set _afb_fj=%_afb_fj:"=%
rem can only supply a filename to the ren command (not path)
for %%i in (%_afb_fj%) do set _afb_fj=%%~ni%%~xi
rem do the rename now
if exist "%_afb_fn%" ren "%_afb_fn%" "%_afb_fj%"
:done
I've got a batch script to utilize a command for an application to create some backups. I've got a loop setup to run through and fetch folder names and then to run the backup operation utilizing those folder names as file names. My loop runs great but my batch script just closes when it is finished. I'd like to escape the loop so I can go back to a choices location I have specified. I've seemingly been unable to escape this loop properly. My code is below:
set /p work=Folder Location:
set /p staging=Location of staging-backup file:
set /p backup=Location to save backup:
#Echo off
md %backup%
setlocal enabledelayedexpansion
set /a $count=1
cd /d %staging%
for /f "delims=" %%a in ('dir "%work%" /b/o') do (
staging-backup "%%a" "%backup%\%%a"
set /a $Count+=1
)
Again, this all runs great (though I can't get it to log properly but thats another battle for later) except I'd love to GOTO CHOICE at the end. When I add it after the closing ) part of the loop, it still closes. When I bring it inside the loop, it closes. Do I need to wrap this loop in an if else to escape it properly?
I tried pulling the code out and pushing it to it's own bat then calling that bat with my original but no change.
:THREE
echo.
echo.
.\Loops.bat
echo.
echo.
GOTO CHOICE
This portion calls it, runs the new bat but still closes the cmd window when it is finished. Any ideas?
#Echo off
setlocal enabledelayedexpansion
:AGAIN
for %%a in (work staging backup) do set "%%a="
set /p "work=Folder Location: "
if not defined work goto :eof
set /p "staging=Location of staging-backup file: "
set /p "backup=Location to save backup: "
md %backup%
set /a $count=1
PUSHD %staging%
for /f "delims=" %%a in ('dir "%work%" /b/A-D') do (
staging-backup "%%a" "%backup%\%%a"
set /a $Count+=1
)
POPD
GOTO AGAIN
Here's a revision.
The first two lines are moved to the top to turn off command-echoing prevent the variables remaining set for each run.
Then insert a label, and clear the variables.
If you reply just Enter to the work prompt, the batch terminates as work will be undefined (set /p leaves the variable unchanged under these circumstances - it does not clear the variable)
PUSHD a directory to switch temporarily to a different directory.
execute staging-backup in that directory. Note that if staging-backup is a batch, then you should use CALL staging-backup... (actually, you could do that with any executable - if it's a batch, you must do it so that cmd knows where to come back to at the end of the destination batch (in this case, staging-backup.bat)
When the for loop is finished, POPD to return to the original directory and loop back to :AGAIN to well - do it all again.
I am trying to write a small .bat script (with limited programming knowledge) that will allow users to enter a value for current version number (e.g. 01) and new version number (e.g. 02) and then use those two numbers inside a rename command.
echo off
cls
TITLE Version Updater
echo Use this script to update file names. This works similar to find and replace in other programs.
echo[
echo Enter the current version number (01 for example)
echo off
set /p current="Current Version: "
echo[
echo Enter the new version number (01 becomes 02 etc.)
echo off
set /p new="New Version: "
echo[
echo You will be updating all occurences of "%current%" in your file names to "%new%", if this is correct then continue, if not close this window.
pause
cd %CD%
rename *%current%* *%new%*
pause
I think the code is almost right, I am just having troubles with making it reference the current directory that it is run from. I am using this script with people who have limited computer skills, and I am not the network administrator so I cannot really do anything too in depth.
If someone could please help me tweak this then that would be great.
Cheers,
Mat
Edit 1 - Comment response
For example, test_01.tab changing to test_02.tab. It basically will replace all _01 parts of the file name and change them to _02. In this case, current = 01 and new = 02. The filenames are all different though, so you may have test_01.bat, testing_01.bat to change, so just renaming the 01 to 02 is how I assumed it would work.
Edit 2 - Current code
This is thanks to Stephan below, I believe the only thing it needs to be working correct is for the file path to be removed from the second part of the REN command so that it just has the file and extension and it should work.
#pushd %~dp0
#Echo off
CLS
setlocal enabledelayedexpansion
set /p current="Current Version: "
set /p new="New Version: "
for /R %%a in (*_%current%*) do (
set "Name=%%~a"
ren "%%~a" "!Name:_%current%=_%new%!"
)
pause
Edit 3 - Final Code (works, yay!)
#pushd %~dp0
#echo off
cls
TITLE CEF File Version Updater
echo This script will update CEF file versions for TLS rejections (E.G. 4XXX_XX_1 to 4XXX_XX_2). Backup files prior to running this script as a safety measure.
echo[
echo Enter the current version number (no underscore)
echo off
set /p current="Current Version: "
echo[
echo Enter the new version number (no underscore)
echo off
set /p new="New Version: "
echo[
echo You will be updating all occurences of "_%current%" in your file names to "_%new%", is this correct?
SET /P ANSWER=Do you want to continue (Y/N)?
if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={yes} (goto :yes)
goto :no
:yes
rename *_%current%.* *_%new%.*
CLS
echo Renaming is complete, please check the new file names are correct.
pause
exit /b 0
:no
exit /b 1
#Echo off
setlocal enabledelayedexpansion
set /p current="Current Version: "
set /p new="New Version: "
for /R %%a in (*_%current%.*) do (
set "Name=%%~nxa"
ECHO ren "%%~a" "!Name:_%current%=_%new%!"
)
pause
(remove ECHO, if the output satisfies you)
This should do the trick.
#Echo off
set /p current="Current Version: "
set /p new="New Version: "
for /R "c:\your location" %%a in (*_%current%.*) do (
ren *_%current%.* *_%new%.*
)
pause
Below is before and after running the script on a couple of test-files.
First post here :) I am new to creating batch files and have created the below batch file (which took me about 3 weeks to figure out, LOL). Basically, when we get a new assignment we copy the template folder and then rename it the next unused folder name, eg. if the last folder was 15-P0028 the next one would be 15-P0029. the batch works perfectly! But, sometimes we want to add a client name to the end of the folder name, eg. 15-P0029 Brown. I want the batch to pause for user input after renaming the folder the next in sequence so we can enter a client name or just hit enter to insert the new folder without the client name. I think using the set /p would work but I have no idea how to use it properly.
Can anyone help me with this, it would be greatly appreciated.
#echo off
setlocal enableDelayedExpansion
cd /d C:\Users\jbrown\Desktop\Test
set I=2
:NextI
if /I %I% LEQ 999 set II=0%I%
if /I %I% LEQ 99 set II=00%I%
if /I %I% LEQ 9 set II=000%I%
if not exist "15-P!II!" (
xcopy /s /e /i "15-P0000-Template" "15-P!II!"
goto :eof
)
set /a I+=1
if /i %I% LSS 9999 goto NextI
)
yep, you got it, you need the /p "prompt" command. Something like this would work
if not exist "15-P!II!" (
set /p "client_name=OPTIONAL Enter a client name and press <ENTER>: "
xcopy /s /e /i "15-P0000-Template" "15-P!II!!client_name!"
goto :eof
)
we don't need to do any extra processing to check if the user entered a value. If they simply pressed enter client_name should just be an empty string. so adding an empty string onto the end won't affect the name