Batch file - passing path name as parameter in command line - batch-file

I want to copy from source to destination only the files with .txt extension. I want to give as parameters in commandline the path name - source and the path name - destination. Here is my batch file Script.bat:
#ECHO OFF
setlocal
set /p source =
set /p destination=
FOR %%f IN (*.txt) DO XCOPY "%source%"\"%%f" "%destination%" /m /y /d /s
I want to call this batch file in cmd so:
cmd> Script.bat "SourceFolder" "DestinationFolder"
But it doesn't work!
Thank you!

Give this a try. It may not be entirely correct, but it should help you get started.
#echo off
setlocal
set /p source =
set /p destination=
xcopy /m /y /d /s "%~source%\*.txt" "%~destination%\"

Supposing correctness of /m /y /d /s xcopy switches this script could work:
#echo off
setlocal
if "%~1"=="" goto :error empty 1
if "%~2"=="" goto :error empty 2
set "source=%~1"
if not exist "%source%\" goto :error not exist 1
set "destination=%~2"
if not exist "%destination%\" goto :error not exist 2
xcopy "%source%\*.txt" "%destination%\" /m /y /d /s
goto :eof
:error
echo wrong parameters %*
goto :eof
See also next resource: Command Line arguments (Parameters)

Related

Batch copy files from list of files in subfolders

I am attempting to copy specific files from a list, "filelist.txt" to a destination folder. With the code presented below, I can only do this from a specific source folder and have only the files names in the text file (as compared to the full path). I wanted to copy files from subfolders in the main folder. How can I do this if I already have the full path of the files that I need copied in the text file?
Here is the start of the code that I have (built from the code presented here):
CODE
#ECHO ON
SET FileList=G:\filelist.txt
SET Source=G:\fold1
SET Destination=G:\Copy1
FOR /F "USEBACKQ TOKENS=*" %%F IN ("%FileList%") DO XCOPY /F /Y "%Source%\%%~F" "%Destination%\"
GOTO :EOF
It worked on my condition
#echo off
set filelist=filelist.txt
set source=StackOverFlow
set destination=copyl
:work
for %%i in (%filelist%) do set filename=%%~nxi
copy /y %filelist% %tmp%
set "filelist=%tmp%\%filename%"
set "filel=%tmp%\file"
:data
set data=con
set /p data=<%filelist%
more +1 "%filelist%" > "%filel%"
del /q /f %filelist%
ren %filel% %filename%
if not exist "%Source%\%data%" goto exitx
copy "%Source%\%Data%" "%Destination%"
goto data
:exitx
del /q /f %filelist%
del /q /f %filel%
cls
echo Operation Complete!
pause
exit
Example of filelist.txt
test.txt
text.bat
test.cmd
biltudas1.md

Log contents of text file before deleting

My script isn't logging the contents of run.txt to log.txt
I've tried to remove the delete command to see if it was deleting it too quickly and therefore couldn't log. But that wasn't the case.
What should I change?
#ECHO OFF &setlocal
SET File=run.txt
type %File%
for /f "tokens=*" %%A in (%File%) do (echo >> log.txt)
del "%File%" /s /f /q > nul
pause
Here is a very simple way to do the task you are requiring.
#echo off
REM Will only grab the first line of the file
set /p file=<run.txt
REM For the last line use a for loop
for /f "tokens=*" %%a in (%file%) do set last_line=%%a
(
echo %file%
)>>log.txt
del /f %file% >nul
If not %errorlevel% equ 0 (
ECHO ERROR - %errorlevel%
pause
exit /b
)
ECHO Success!
timeout /t 003
exit /b %errorlevel%
EXPLANATION
set /p is for set prompt. For more information you can use set /? in your CMD window or check out this site.
I wish I could speak more on what < does, but what it is doing here is piping the content of run.txt to our variable.
Then we echo out our variable to our log file with (ECHO This is our %file%)>>destination
>> is to append where > is to overwrite the file.
(
echo %file%
echo.
)>>%file%
Checking for an error is probably unnecessary, but I believe it is a good habit to build on which is what I am trying to do with that If not %errorlevel% statement.
No error? We Success and timeout ourselves for xxx seconds.
Try:
#ECHO OFF &setlocal
SET "File=run.txt"
type "%File%" >> "log.txt" && (del "%File%" /f > nul)
pause

Batch file to input multiple file types and segregate them as per file type

#echo off
set /p var=Enter source folder:
set /p var1=Enter destination folder:
set /p var2=Select Filer:
xcopy /f /j /s /z /c /y "%var%\*.%var2%" "%var1%\%var2%"
I have written above batch file, I need it should take multiple filters like HTM, XML etc and paste them in destination folder (create folders same as filter name) and segregate them as per filters.
Here is your batch code extended as requested and commented:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
rem For source and target folder predefine the variables with
rem a double quote as value to avoid a syntax error in case of
rem user just hits key RETURN or ENTER without entering anything.
:EnterSource
set "SourceFolder=""
set /P "SourceFolder=Enter source folder: "
rem Remove all double quotes from enter string.
set "SourceFolder=!SourceFolder:"=!"
rem Check if the remaining string is an empty string.
if "%SourceFolder%" == "" goto EnterSource
rem Replace all slashes by backslashes
set "SourceFolder=!SourceFolder:/=\!"
rem Remove a trailing backslash.
if "%SourceFolder:~-1%" == "\" set "SourceFolder=!SourceFolder:~0,-1!"
rem Check if source folder exists.
if not exist "%SourceFolder%\*" goto EnterSource
echo.
:EnterTarget
set "TargetFolder=""
set /P "TargetFolder=Enter target folder: "
set "TargetFolder=!TargetFolder:"=!"
if "%TargetFolder%" == "" goto EnterTarget
set "TargetFolder=!TargetFolder:/=\!"
if "%TargetFolder:~-1%" == "\" set "TargetFolder=!TargetFolder:~0,-1!"
echo.
echo Multiple select filter can be entered separated by spaces.
echo.
echo For example: *.txt *.htm *.log
echo.
echo The default is: *
echo.
:EnterFilter
set "SelectFilter=*"
set /P "SelectFilter=Select filter: "
set "SelectFilter=!SelectFilter:"=!"
if "%SelectFilter%" == "" goto EnterFilter
rem Run xcopy for each filter specified. The command FOR is used to separate
rem the string on spaces. Only the first token (= first filer) is always
rem used for a single XCOPY execution and the remaining token (= filters)
rem are assigned again to variable SelectFilter. After each execution of
rem XCOPY it is checked if there are more folters to process and therefore
rem if FOR and XCOPY must be executed once more.
:CopyLoop
for /F "tokens=1*" %%I in ("%SelectFilter%") do (
call :GetFileType "%%~xI"
xcopy "%SourceFolder%\%%I" "%TargetFolder%\!FileType!" /C /F /H /I /K /R /S /Y
set "SelectFilter=%%J"
)
if not "%SelectFilter%" == "" goto CopyLoop
endlocal
goto :EOF
rem This function TRIES to get from file extension string according to
rem filter specification just the file type using string substitutions.
rem The command goto :EOF results in exiting the function an returning
rem to CopyLoop above with continuing the execution on command XCOPY.
:GetFileType
set "FileType=%~1"
rem The passed file type string could be an empty string if the filter
rem specification is for example "File*" without a file extension.
if "%FileType%" == "" goto :EOF
rem Remove the period at beginning of file type string. It is
rem guaranteed that there is only one period in the entire file
rem type string which is at beginning if there is one at all.
set "FileType=%FileType:.=%"
rem The file type string could be now an empty string if the filter
rem specification is for example just "*" to match all files.
if "%FileType%" == "" goto :EOF
rem Remove an asterisk at end of file type string if there is one.
if "%FileType:~-1%" == "*" set "FileType=%FileType:~0,-1%"
rem The file type string could be now an empty string
rem if the filter specification is for example "*.*".
if "%FileType%" == "" goto :EOF
rem Remove everything after first wildcard character
rem for example if filter specification is "*.php?".
for /F "tokens=1 delims=*?" %%T in ("%FileType%") do set "FileType=%%T"
if "%FileType%" == "" goto :EOF
rem Remove all question marks if the file type string
rem consists now only of 1 or more question marks.
set "FileType=%FileType:?=%"
rem The file type string could be now an empty string if
rem the filter specification is for example "Image*.???".
if "%FileType%" == "" goto :EOF
rem Append a backslash to not empty file type string for XCOPY.
set "FileType=%FileType%\"
goto :EOF
An example for most difficult task to solve: getting file type from filter specifications:
Source folder is: C:\Temp\Source
Target folder is: C:\Temp\Target
Select filter is: * *.* *.txt *.htm* *.php? File* x.y.* File_??.* Image*.???
The XCOPY commands executed are:
xcopy "C:\Temp\Source\*" "C:\Temp\Target\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\*.*" "C:\Temp\Target\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\*.txt" "C:\Temp\Target\txt" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\*.htm*" "C:\Temp\Target\htm\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\*.php?" "C:\Temp\Target\php\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\File*" "C:\Temp\Target\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\x.y.*" "C:\Temp\Target\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\File_??.*" "C:\Temp\Target\" /C /F /H /I /K /R /S /Y
xcopy "C:\Temp\Source\Image*.???" "C:\Temp\Target\" /C /F /H /I /K /R /S /Y
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 /?
rem /?
set /?
setlocal /?
xcopy /?

Batch file perform task in directories recursively when the directory name contains "&"

I made a batch program to perform some simple tasks in directories recursively and it usually works without problems. but if the directory name contains "&", I got an error.
#echo off
setlocal enableextensions disabledelayedexpansion
set "exitCode=0"
set "BaseDir=%~1"
if not defined BaseDir set "BaseDir=%CD%"
for %%f in ("%BaseDir%") do set "BaseDir=%%~ff"
if not exist "%BaseDir%" (
call :error "Base directory does not exist"
goto endProcess
)
call :recursive "%BaseDir%"
if errorlevel 1 set "exitCode=1"
goto :endProcess
:Whattodo
echo %CD%
goto :eof
:recursive BaseDir
setlocal
set "BaseDir=%~f1"
pushd "%BaseDir%"
for /d %%d in (*) do if not errorlevel 1 call :recursive "%%~fd"
call :Whattodo
popd
endlocal
goto :eof
:error
echo(%~1
set "exitCode=1" & cmd /d /q /c exit /b 1
goto :eof
:endProcess
endlocal & exit /b %exitCode%
I will get a output like this:
C:\tmp\01\04
C:\tmp\01\05
C:\tmp\01
C:\tmp\02\06
C:\tmp\02\07\08
C:\tmp\02\07
C:\tmp\02
C:\tmp\03
C:\tmp
but if I have a directory like this "C:\tmp\02\06 & a" I will have this output
C:\tmp\01\04
C:\tmp\01\05
C:\tmp\01
C:\tmp\02\06
'a' is not recognized as an internal or external command,
C:\tmp\02
C:\tmp
I understand that the problem is in the line below, but I don't know how to solve it.
for /d %%d in (*) do if not errorlevel 1 call :recursive "%%~fd"
!! edit
Before I posted it I tried what I can to debug the error. echo %CD% just print the current directory, to help me debug. Could be cd and the error will persist. (I tried)
What I could find out, the variable "%%~fd" is expanded and than the line is processing.
In this way call pass "C:\tmp\02\06" (instead of "C:\tmp\02\06 & a") and try to execult the command a
Like rojo said, your problem is located in the :Whattodo function.
Replace echo %CD% with echo !CD! and it should work.
As percent expansion is vulnerable to special characters, but delayed expansion isn't.
If you don't want to enable it always, you can enabled it only in the function.
:Whattodo
setlocal EnableDelayedExpansion
echo !CD!
endlocal
goto :eof

modify batch that copy in clipbrd older filename .mxf in folderA that are not in folderB

Thanks to foxidrive I have this code:
batch to copy in clipbrd filenameandpath of the older file in folderA except the same name in folderB
#echo off
:loop
set "d="
set "done="
set /p "d=Type source path (or press enter for current folder): "
if not defined d set "d=%cd%"
if not exist "%d%" echo Enter valid path - try again & goto :loop
cd /d "%d%"
for /f "delims=" %%a in ('dir *.mxf /b /od /a-d') do (
if defined done goto :EOF
if not exist "d:\folderB\%%~na.*" (
echo %%~fa|clip >nul
set done=1
)
)
OK, it work very well, thanks!
now I should like to do this:
and then the batch have to nename a file o:\temp.avi with the filename choosed by the batch (and putted into the clipbrd) example: if the batch have choose (into folderA) C0001.mxf, it have to rename o:\temp.avi --------> C0001.avi
Add the line in the middle between the other two.
echo %%~fa|clip >nul
ren "o:\temp.avi" "%%~nxa.avi"
set done=1
Read the help section on how Stack Overflow works: https://stackoverflow.com/tour

Resources