I have the following MS Windows batch file code:
#echo off
cd\
dir/s *.docx *.xlsx *.ppt *.docx
SET /p input= %data% "
copy "%data%" C:\abc\
pause
This command shows all 4 types of extension list all over drives, but I want to take input from user and then copy to the desired location.
What am I missing?
Your main mistake is assigning the string entered by the user of the batch file to environment variable input but referencing on command copy the environment variable data which is not defined at all and therefore %data% is replaced twice before execution of the command line by nothing.
What about using this batch code?
#echo off
rem The next 2 commands are commented out as not needed for this task.
rem cd \
rem dir /s *.doc *.docx *.xlsx *.ppt
setlocal EnableExtensions EnableDelayedExpansion
:UserPrompt
echo/
echo Enter the file name with complete path or drag and drop
echo the file to copy from Windows Explorer over this window.
echo/
set "FileName=""
set /p "FileName=Enter file name: "
echo/
rem Remove all double quotes from entered string.
set "FileName=!FileName:"=!"
rem Has the user entered any file name at all?
if "!FileName!" == "" goto UserPrompt
rem Does the file really exist?
if exist "!FileName!" goto CopyFile
echo Error: The specified file does not exist.
echo/
goto UserPrompt
:CopyFile
copy "!FileName!" C:\abc\
echo/
endlocal
pause
Read the answer on Why is string comparison after prompting user for a string/option not working as expected? for an explanation on all the extra code used here.
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.
copy /?
echo /?
endlocal /?
goto /?
if /?
pause /?
rem /?
set /?
setlocal /?
Related
:exe
dir /a plugins
cls
set /p load="Which file do you want to load?: "
if exist plugins\%load%.bat goto loadtrue
if not exist plugins\%load%.bat goto loadfail
:loadfail
cls
echo error, file does not exist or you typed the file name wrong, try again
pause
goto exe
:loadtrue
cls
start %load%.bat
pause
goto terminal
Here is a batch file with comments which are the lines starting with rem:
#echo off
:UserPrompt
cls
rem Output the names of all batch files in subdirectory plugins in directory
rem of this batch file without file extension and next an empty line.
for /F "eol=| delims=" %%I in ('dir "%~dp0plugins\*.bat" /A /B 2^>nul') do echo %%~nI
echo/
rem Make sure the environment variable Load is not defined by chance
rem for example by a previous execution of this batch file in same
rem Windows command prompt window.
set "Load="
rem Prompt the user for the batch file name to load respectively execute.
set /P "Load=Which file do you want to load? "
rem Has the user input anything at all?
if not defined Load goto UserPrompt
rem Remove all double quotes from input string.
set "Load=%Load:"=%"
rem Is there anything left after removing all double quotes?
if not defined Load goto UserPrompt
rem Is there a batch file with user input name in subdirectory plugins
rem in the directory containing this batch file?
if exist "%~dp0plugins\%Load%.bat" goto StartPlugin
echo/
echo Error: The file name was typed wrong.
echo Please try it again.
echo/
pause
goto UserPrompt
:StartPlugin
cls
rem Start a separate command process for execution of the user selected
rem batch file with window title of console window set to name of batch
rem file and current directory set to subdirectory plugins of the
rem directory containing this batch file.
start "%Load%" /D"%~dp0plugins" ".\%Load%.bat"
pause
goto Terminal
:Terminal
I recommend to read in addition to the comments:
What does %~dp0 mean, and how does it work?
What is the reason for batch file path referenced with %~dp0 sometimes changes on changing directory?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/
Please note that the directory path referenced with %~dp0 always ends with a backslash and therefore concatenation of this path with a directory or file name should be done without an additional backslash as shown in code above even if it makes the file/folder strings more difficult to read.
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.
cls /?
dir /?
echo /?
for /?
goto /?
if /?
pause /?
rem /?
set /?
start /?
I am new to batch scripting
I am supposed to write a batch file to read a text file and two command line parameter say ,"task" and "choice".There can be two values for choice-"enable" and "disable"
Now i would want to input the file line by line and match the starting of line with "task" command line argument entered followed by a colon(:) followed by anything .
Now if the choice is "enable" then i have to put ":N" in the respective lines in which the task matches if it doesnt contain a :N already
My text file would contain entries like:
24343:abc:dsd:N
233:zxzxzc
2344:cxzc:xzc
and if i run a command like
myscript.bat 2344 enable
the output of the script should be that the file should be
24343:abc:dsd:N
233:zxzxzc
2344:cxzc:xzc:N
I have been trying to write the code for this for two whole days but still havent been successful.
After all the reading,this is what i have written till now
#echo off
set /A taskname= %1
set choice= %2
FOR /F "tokens=* delims=" %%x in (testdoc.txt) do (
echo %x%|findstr /R "^'%1'.*[^:][^N]$"
if errorlevel 1 (echo does not contain) else (echo contains)
)
In this,i was trying to compare line by line with the regex but it doesnt work as intended.
Any help would be appreciated
Thanks
Regular expression replaces are not possible with pure usage of Windows command line interpreter cmd.exe or the console applications installed with Windows. This would require usage of a scripting language/interpreter with support for regular expression replaces in files like PowerShell or JScript which would be most likely better choices for this task.
However, a pure batch file solution is also possible for this task as it can be seen on commented batch code below with lots of extra features.
#echo off
set "TempFile=
rem Is first parameter /? for getting help?
if "%~1" == "/?" goto ShowHelp
rem Is the batch file not started with any none empty parameter?
if not "%~1" == "" (
rem Does the first parameter not consist of only digits 0-9?
for /F "delims=0123456789" %%I in ("%~1") do goto ShowHelp
)
rem Is there also specified a second parameter?
if not "%~2" == "" (
rem Is the second parameter neither enable nor disable (case-insensitive)?
if /I not "%~2" == "disable" if /I not "%~2" == "enable" goto ShowHelp
)
rem Setup a local environment for this batch file.
setlocal EnableExtensions DisableDelayedExpansion
rem Define the name of the text file without or with path to modify.
rem Define the name of the temporary file needed to modify the file.
set "TextFile=TextFile.txt"
set "TempFile=%TEMP%\%~n0.tmp"
rem Does the text file to modify exist at all?
if not exist "%TextFile%" goto MissingFile
rem Was a task number specified on starting this batch file?
if not "%~1" == "" set "TaskNumber=%~1" & goto FindTask
rem Prompt the user for the task number and make sure that the user really
rem enters a number by verifying user input using a very secure method.
:PromptNumber
set "TaskNumber="
set /P "TaskNumber=Enter task number: "
if not defined TaskNumber goto PromptNumber
setlocal EnableDelayedExpansion
for /F "delims=0123456789" %%I in ("!TaskNumber!") do endlocal & goto PromptNumber
endlocal
:FindTask
rem Does the file to modify contain the number at beginning of a
rem line as specified with first parameter and followed by a colon?
%SystemRoot%\System32\findstr.exe /B /L /M /C:"%TaskNumber%:" "%TextFile%" >nul 2>&1
if errorlevel 1 goto MissingNumber
rem Has the user specified the action to perform as second parameter.
if /I "%~2" == "enable" set "TaskAction=1" & goto ModifyFile
if /I "%~2" == "disable" set "TaskAction=2" & goto ModifyFile
rem Prompt the user for the action to perform.
%SystemRoot%\System32\choice.exe /N /M "Press Y to enable or N to disable task: "
set "TaskAction=%ERRORLEVEL%"
rem Copy the file with ignoring empty lines and lines starting with a
rem semicolon to temporary file with modifying all lines starting with
rem the specified task number according to specified action to perform.
rem But delete the temporary file before if existing by chance.
:ModifyFile
del "%TempFile%" 2>nul
set "FileModified="
for /F "usebackq tokens=1* delims=:" %%I in ("%TextFile%") do (
if not "%%I" == "%TaskNumber%" (
echo %%I:%%J>>"%TempFile%"
) else (
set "TextLine=%%I:%%J"
call :ModifyLine
)
)
rem Was no line modified on copying all the lines to temporary file?
if not defined FileModified del "%TempFile%" & goto EndBatch
rem Move the temporary file over the text file to modify.
move /Y "%TempFile%" "%TextFile%" 2>nul
rem Was the text file overwritten by command MOVE?
if not errorlevel 1 goto EndBatch
rem Inform the user that the text file to modify could not be
rem modified because of being read-only or missing appropriate
rem NTFS permissions or a sharing access violation occurred.
del "%TempFile%"
for /F %%I in ("%TextFile%") do set "TextFile=%%~fI"
echo/
echo ERROR: "%TextFile%" could not be modifed.
echo/
echo Please make sure the file has not read-only attribute
echo set, is not opened in any application and you have
echo the necessary permissions to overwrite this file.
goto HaltBatch
rem This is a subroutine which modifies a line with right task
rem number according to action to perform and outputs this line
rem into the temporary file. It records also if the line needed
rem to be modified at all.
:ModifyLine
if %TaskAction% == 1 (
if not "%TextLine:~-2%" == ":N" (
set "TextLine=%TextLine%:N"
set "FileModified=1"
)
) else (
if "%TextLine:~-2%" == ":N" (
set "TextLine=%TextLine:~0,-2%"
set "FileModified=1"
)
)
>>"%TempFile%" echo %TextLine%
goto :EOF
rem Get name of file with full path which works also for not existing
rem file and inform the user about missing file to modify with full
rem path to see also where this batch file expected it on execution.
:MissingFile
for /F %%I in ("%TextFile%") do set "TextFile=%%~fI"
echo/
echo ERROR: "%TextFile%" does not exist.
goto HaltBatch
:MissingNumber
rem The specified number does not exist in the file to modify
rem at beginning of a line. Inform the user about this error.
echo/
echo ERROR: %TaskNumber% not found in file "%TextFile%".
goto HaltBatch
:ShowHelp
echo/
echo Usage: %~nx0 [task] [disable ^| enable]
echo/
echo task ...... number of the task to enable or disable.
echo disable ... disable the specified task.
echo enable .... enable the specified task.
echo/
echo %~nx0 can be also started without any parameter.
echo In this case the task number and the action to perform
echo can be entered during the execution of the batch file.
:HaltBatch
echo/
pause
echo/
:EndBatch
if defined TempFile endlocal
The command line set "TextFile=TextFile.txt" must be modified to your environment.
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 /?
choice /?
del /?
echo /?
endlocal /?
findstr /?
for /?
goto /?
if /?
move /?
pause /?
rem /?
set /?
setlocal /?
Further read following:
DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/
Microsoft article about Using Command Redirection Operators
Stack Overflow answer on Where does GOTO :EOF return to?
Stack Overflow answer on Single line with multiple commands using Windows batch file
I have a *.txt file that consist of a very long list of files (about 30k) to be moved and where each line contains the file name of the file to move with full path and the target folder with full path separated by the string to .
List file example:
C:\USER\BDG\anto\12.jpg to D:\USER\BDG\,
C:\USER\SMG\kent\311.jpg to D:\USER\SMG\,
C:\USER\JKT\lydia\13121.jpg to D:\USER\JKT\,
C:\USER\NYC\tiffany\1e1b1.jpg to D:\USER\NYC\,
C:\USER\MNC\regent\1eb1be1.jpg to D:\USER\MNC\,
etc.
How to process this list file line by line to move all the files to specified folder?
The easiest method would have been opening the list file in a text editor with support for Perl regular expression find/replace and running a Perl regular expression replace all from top of file with search string ^(.+?) to (.+),$ and replace string #move "\1" "\2". The result would have been:
#move "C:\USER\BDG\anto\12.jpg" "D:\USER\BDG\"
#move "C:\USER\SMG\kent\311.jpg" "D:\USER\SMG\"
#move "C:\USER\JKT\lydia\13121.jpg" "D:\USER\JKT\"
#move "C:\USER\NYC\tiffany\1e1b1.jpg" "D:\USER\NYC\"
#move "C:\USER\MNC\regent\1eb1be1.jpg" "D:\USER\MNC\"
Then modified list file could have been saved next for example as MoveFiles.bat with ANSI encoding and executed with double clicking on it, or from within a command prompt window to see possible error messages in case of a file could not be moved for various reasons.
However, here is a small batch file for this task processing the list file ListFile.txt.
#echo off
if not exist "ListFile.txt" goto :EOF
setlocal EnableExtensions DisableDelayedExpansion
set "MoveError=0"
for /F "usebackq eol=| delims=" %%L in ("ListFile.txt") do call :ProcessFile "%%L"
if %MoveError% == 1 echo/ & pause
endlocal
goto :EOF
:ProcessFile
set "ListLine=%~1"
rem Remove comma at end of line if there is one at all.
if "%ListLine:~-1%" == "," set "ListLine=%ListLine:~0,-1%"
rem Replace " to " by a vertical bar being an invalid character in a file
rem name. The string " to " exists hopefully only once in each line.
set "ListLine=%ListLine: to =|%"
rem Split up the line into two substrings using | as delimiter.
rem First string is the file to move, second the target directory.
rem Execute the file move and output an error message on failure.
for /F "tokens=1,2 eol=| delims=|" %%I in ("%ListLine%") do (
move "%%~I" "%%~J" >nul 2>&1
if not errorlevel 1 goto :EOF
if %MoveError% == 1 echo/
echo ERROR: Failed to move the file
echo "%%~I"
echo to "%%~J"
set "MoveError=1"
)
goto :EOF
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 /?
if /?
move /?
rem /?
set /?
setlocal /?
See also:
Microsoft support article Testing for a Specific Error Level in Batch Files
Microsoft TechNet article Using Command Redirection Operators
Stack Overflow answer on Where does GOTO :EOF return to?
Am trying to extract a RAR file to a directory (C:\autoexe\source). Here the "autoexe" folder name changes everyday. The fullname does not change, the constant thing is "auto" in the string "autoexe", the exe part changes. I tried the below
for /f "delims=" %%a in ('dir /b "%cd%\samples\package.rar"') do start "" "%ProgramFiles%\WinRAR\WinRAR.exe" x -ibck "%cd%\samples\package.rar" *.* "%cd%\auto * \source"
This commented batch code with error handling should do the job:
#echo off
rem Get name of first non hidden subfolder starting with auto in current folder.
for /D %%I in (auto*) do set "FolderName=%%I" & goto CheckArchive
echo Error: There is no auto* folder in: "%CD%"
echo/
pause
goto :EOF
:CheckArchive
if exist "samples\package.rar" goto ExtractArchive
echo Error: There is no file "package.rar" in subfolder "samples" of
echo folder: "%CD%"
echo/
pause
goto :EOF
:ExtractArchive
"%ProgramFiles%\WinRAR\UnRAR.exe" x -c- -idq -y -- "samples\package.rar" "%FolderName%\"
if not errorlevel 1 goto :EOF
echo/
echo/
pause
Read text file Rar.txt in program files folder of WinRAR for details on the used switches on UnRAR command line or run UnRAR.exe from within a command prompt window without any option to get displayed a brief help on how to use this freeware console application.
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.
echo /?
for /?
goto /?
if /?
pause /?
set /?
Read answer on Single line with multiple commands using Windows batch file for an explanation of & operator. And read the Microsoft support article Testing for a Specific Error Level in Batch Files.
I want to copy more than 1000 files from a source folder like
sourcefolder\prod_de_7290022.xlsx
sourcefolder\prod_de_1652899.xlsx
sourcefolder\prod_de_6272899.xlsx
sourcefolder\prod_de_6189020.xlsx
sourcefolder\prod_de_7290022.wav
sourcefolder\prod_de_1652899.wav
sourcefolder\prod_de_6272899.wav
sourcefolder\prod_de_6189020.wav
sourcefolder\prod_de_7290022_mark.xlsx
sourcefolder\prod_de_1652899_mark.xlsx
sourcefolder\prod_de_6272899_mark.xlsx
sourcefolder\prod_de_6189020_mark.xlsx
to the right destination folder. The folder names are - based on another routine - long and only the first 15 characters are identical with the first 15 characters of each file name, like:
destination\prod_de_1652899_tool_big\
destination\prod_de_6272899_bike_red\
destination\prod_de_6189020_bike-green\
destination\prod_de_7290022_camera_good\
I am looking for a routine to copy the files into the folder, like sourcefolder\prod_de_1652899.xlsx into destination\prod_de_1652899_tool_big\.
Is here anyone with a good idea for a batch/script?
I suggest to use this commented batch code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=sourcefolder"
set "TargetFolder=destination"
rem Call subroutine CopyFile for each non hidden and
rem non system file found in specified source folder
rem and then exit processing of this batch file.
for %%I in ("%SourceFolder%\*") do call :CopyFile "%%~fI"
endlocal
goto :EOF
rem This is a subroutine called for each file in source folder.
rem It takes the first 15 characters from each file name passed
rem to this subroutine via first parameter and search for a
rem folder in target folder starting with same 15 characters.
rem If such a folder is found, the file is copied to this folder
rem and the subroutine is exited.
rem Otherwise a new folder is created for the file and if
rem this is indeed successful, the file is copied into the
rem newly created folder with an appropriate message.
:CopyFile
set "FileName=%~n1"
set "DirectoryName=%FileName:~0,15%"
for /D %%D in ("%TargetFolder%\%DirectoryName%*") do (
copy /B /Y %1 /B "%%~D\" >nul
goto :EOF
)
set "NewFolder=%TargetFolder%\%DirectoryName%_new"
md "%NewFolder%"
if exist "%NewFolder%\" (
echo Created new folder: %NewFolder%
copy /B /Y %1 /B "%NewFolder%\" >nul
goto :EOF
)
echo Failed to create folder: %NewFolder%
echo Could not copy file: %1
goto :EOF
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
call /?
copy /?
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?