Batch: for /f +xcopy output - Save to .log - scripting

I have the next script, and I need it to save all the xcopy files copy outputs to one log file,
:tmdeploy
title Deploying Edithor - %deployer%
set src_folder=S:\ApliTelinver\Compilacion\Edithor 10.5\CompilacionQA
set dst_folder=S:\ApliTelinver\Ambientes-Edithor\Sincronizacion\Test\Test-Mantenimiento
set filelist=filelist-tm.txt
echo Origen: %src_folder%
echo Destino: %dst_folder%
echo.
REM for /f %%i in (%filelist%) DO xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" > "%dd%.log"
for /f "delims=" %%i in (%filelist%) do (
xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" > "%dd%.log"
)
echo.
pause
goto end
The problem is that I only get the last file copy in the output. And how to properly do a timestamp for .log file?
Thank you

You should use the appended redirection operator, >> instead of >.
So, your for loop will look like this:
REM for /f %%i in (%filelist%) DO xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" >> "%dd%.log"
for /f "delims=" %%i in (%filelist%) do (
xcopy /S/E/U/Y "%src_folder%\%%i" "%dst_folder%" >> "%dd%.log"
)

Related

Batch file to zip Apache Tomcat for windows file names that do not equal to today

We have a number of Apache Tomcat for Windows logs - for example..
server.log.2014-02-04-10
server.log.2014-02-04-11
server.log.2014-02-04-12
server.log.2014-02-05-13
server.log.2014-02-05-14
server.log.2014-02-05-15
These are defined with a file extension of .YYYY-MM-DD-HH and by default Apache has them by date: .YYYY-MM-DD however, we have to define the HH breakover because of system usage and other reasons.
I am trying to do something very simple..
If the file extension does not equal today, to archive (zip) it up..
Here is what I have and no matter what I do is that it shows: 2014-02-05 even though the script is showing .2014-02-04.
Here is the script and I am not sure if I need SETLOCAL enabledelayexpansion..
rem http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace
SETLOCAL enabledelayedexpansion
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x
set today=!MyDate:~0,4!-!MyDate:~4,2!-!MyDate:~6,2!
rem today=%MyDate:~0,8%
for %%i in (D:\11\*.*) do (
SET FILETIME=%%~xi
rem SET Dt=!FILETIME:~0,11!
rem IF NOT "!fldt!" == ".!today!" (
rem echo %%~ni%%~xi
rem )
)
pause
Thanks
This filters the filenames by the date string in the name and
will echo the filenames that do not have todays date in them.
#echo off
rem http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace
SETLOCAL enabledelayedexpansion
for /f %%x in ('wmic os get localdatetime ^|find "." ') do set "MyDate=%%x"
set "today=!MyDate:~0,4!-!MyDate:~4,2!-!MyDate:~6,2!"
rem set "today=%MyDate:~0,8%"
for /f "delims=" %%a in ('dir "D:\11\*.*" /b ^|find /v ".%today%-" ') do (
echo "%%~fa"
)
pause

batch rename directories from "NOTE" to "NOTES"

I would like to rename directories whose name contains the word "NOTE", but not "NOTES", to "NOTES". I first experiment with the echo command.
for /f "tokens=1-7" %%i in ('dir d:\mydirectory /s /b /ad ^|find "NOTE" ^|find "NOTES" /v') do #echo %%i %%j %%k %%l %%m %%n %%oS
Because directory names have different spaces in them, the above command may leave spaces between "NOTE" and S. Anyway to overcome this problem?
Give this a burl. If it echo's the right rename command then remove the echo and the pause to activate it. It's untested. Paths containing ! and % characters will cause an issue.
#echo off
setlocal enabledelayedexpansion
for /d /r %%a in (*) do (
set "f=%%~nxa"
if not "!f:NOTE=!"=="%%~nxa" (
if "!f:NOTES=!"=="%%~nxa" (
echo ren "%%a" "!f:NOTE=NOTES!"
pause
)
)
)

Using a bat file to create a log

I am trying to monitor the install of software on our servers remotly with a script by checking the .dll file version. I am not sure if this can be done but after the install on all of the servers I would like to run a bat file to look at all of the servers and create a log file with the server name and that .dll file version number. Suggestions would be great. Thanks.
First download STRINGS.EXE from here (to handle unicode).
http://technet.microsoft.com/en-us/sysinternals/bb897439.aspx
Here is a little something I have been using for quite a while. It does a bit more than you asked for but maybe someone else would prefer to have all of this. You can easily delete the parts you don't want. Add/remove file types as you like and remove the output sections you don't want. It does not do exactly what you asked but the hard part is done and you can adapt as you see fit. Save the code as FileVersions.bat (or whatever). Put this bat file and the downloaded STRINGS.EXE in the same folder. Execute this bat file to get output in FileVersions.txt (or whatever you name bat file). It will look something like this. Gets versions for all specified file types in folders underneath the current folder. Get this modified as you desire and then handle multiple machines as you see fit.
====== Output ============
Versions for *.dll *.ocx *.exe files - Thu 08/08/2013 21:13:28.17
File=C:\Drivers\storage\strings.exe
FileDesc=strings
FileVer=2.41
ProductName=Sysinternals Strings
ProductVer=2.41
File=C:\Drivers\storage\R159108\TEACico2.dll
FileDesc=TEACico2.DLL
FileVer=1, 1, 0, 0
ProductName= TEACico2 DLL
ProductVer=1, 1, 0, 0
====== End of Output ============
#ECHO OFF
TITLE %~n0
PUSHD %~dp0
SET FileTypes=*.dll *.ocx *.exe
SET OutFile=%~n0.txt
IF EXIST %OutFile% DEL /q %OutFile%
ECHO.Retrieving file versions for %FileTypes% files
ECHO.
ECHO.Versions for %FileTypes% files - %Date% %Time% > %OutFile%
ECHO.
FOR /R "%CD%" %%A IN (%FileTypes%) DO ECHO.%%A & CALL :FileVersion "%%A" >> %OutFile%
ECHO.
ECHO.Results are in %OutFile%
pause
GOTO :eof
REM ========================= Subroutines =========================
:FileVersion
SETLOCAL
ECHO.
ECHO.File=%~1
SET LineNum=Invalid
FOR /F "tokens=1 delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND /I "FileDescription"') DO SET LineNum=%%A
IF %LineNum%==Invalid GOTO :FileVer
SET /A LineNum += 1
FOR /F "tokens=1* delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND "[%LineNum%]"') DO SET FileDesc=%%B
IF NOT "%FileDesc%"=="FileVersion" SET FileDesc
:FileVer
SET LineNum=Invalid
FOR /F "tokens=1 delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND /I "FileVersion"') DO SET LineNum=%%A
IF %LineNum%==Invalid GOTO :ProductName
SET /A LineNum += 1
FOR /F "tokens=1* delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND "[%LineNum%]"') DO SET FileVer=%%B
SET FileVer
:ProductName
SET LineNum=Invalid
FOR /F "tokens=1 delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND /I "ProductName"') DO SET LineNum=%%A
IF %LineNum%==Invalid GOTO :ProductVer
SET /A LineNum += 1
FOR /F "tokens=1* delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND "[%LineNum%]"') DO SET ProductName=%%B
IF NOT "%ProductName%"=="ProductVersion" SET ProductName
:ProductVer
SET LineNum=Invalid
FOR /F "tokens=1 delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND /I "ProductVersion"') DO SET LineNum=%%A
IF %LineNum%==Invalid GOTO :Done
SET /A LineNum += 1
FOR /F "tokens=1* delims=[]" %%A IN ('STRINGS %1 ^| FIND /N /V "" ^| FIND "[%LineNum%]"') DO SET ProductVer=%%B
SET ProductVer
:Done
ENDLOCAL
GOTO:EOF

returning var back to calling batch file

i start a batch file to process some code, at a time it calls another batchfile and should get returned a variable, but the methods explained in man pages about local/endlocal seem not to work here, what am i doin wrong please?
first batch file:
#ECHO OFF
setlocal
call secondbatchfile.bat xyz
echo. [%val1%]
second batch file:
#if (#a==#b) #end /* <== btw what does this code do ???
#echo off
setlocal enabledelayedexpansion
set "URL=%~1"
set bla bla ...
do bla bla ...
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (
rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"
rem test that trimmed line matches "variable=number"
echo !line! | findstr /i "^to[a-z]*=[0-9]*" >NUL && (
rem test was successful. Scrape number.
for /f "tokens=2 delims==" %%x in ("%%I") do set "val1=%%x"
echo !val1! <== this works
ENDLOCAL & SET top=%val1% <== this not
)
)
this results in:
c:\test>firstbatchfile.bat
123456789 <== this works
[] <== this not
i tried different syntax of return var like !val1! or %%val1 - none worked. what am i missing?
UPDATE:
regarding to other example here on site i tried:
call seconbatchfile.bat xyz ret1
echo. [%2%] [%ret1%]
and in secon file changed:
rem ENDLOCAL & SET %2=!val1!
does not work either?
SOLUTION:
second batch file can be origin script from rojo reading out the whole website, i did leave the trim and match syntax lines to only return relevant matches:
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (
rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"
rem test that trimmed line matches "variable=number"
echo !line! | findstr /i "^[a-z]*=[0-9]*" >NUL && (
echo(%%I
)
)
and the first batch file calling it will do the search for two needed parameters like this:
#ECHO OFF
setlocal
for /f "delims=" %%I in ('secondbatchfile.bat "http://xyz"') do (
echo %%I | findstr /i "top" >NUL && (
for /f "tokens=2 delims==" %%x in ("%%I") do (
set "updir=%%x"
)
)
echo %%I | findstr /i "low" >NUL && (
for /f "tokens=2 delims==" %%x in ("%%I") do (
set "lowdir=%%x"
)
)
)
echo.[%updir%]
echo.[%lowdir%]
many thanks to rojo for fantastic code
The easiest solution is to have your second batch file echo its result, and capture it using a for loop in the first batch file. Cancelling your setlocal to pass an environment variable back to the calling script is a messy affair.
first.bat:
#echo off
setlocal
for %%x in (
"http://10.0.0.1/foo/vars.txt"
"http://10.0.0.1/bar/vars.txt"
"http://10.0.0.1/baz/vars.txt"
"http://10.0.0.1/qux/vars.txt"
"http://10.0.0.1/corge/vars.txt"
) do (
for /f "delims=" %%I in ('fetchvalue.bat "%%~x"') do (
set "val1=%%I"
)
echo.[%val1%]
)
fetchvalue.bat:
#if (#a==#b) #end /*
:: fetchvalue.bat <url>
:: output the "value" part of variable=value from a text file served by http
#echo off
setlocal
if "%~1"=="" goto usage
echo "%~1" | findstr /i "https*://" >NUL || goto usage
set "URL=%~1"
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (
rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"
rem test that trimmed line matches "variable=number"
echo !line! | findstr /i "^to[a-z]*=[0-9]*" >NUL && (
rem test was successful. Scrape number.
for /f "tokens=2 delims==" %%x in ("%%I") do echo(%%x
)
)
goto :EOF
:usage
echo Usage: %~nx0 URL
echo for example: %~nx0 http://www.google.com/
echo;
echo The URL must be fully qualified, including the http:// or https://
goto :EOF
JScript */
var x=new ActiveXObject("Microsoft.XMLHTTP");
x.open("GET",WSH.Arguments(0),true);
x.setRequestHeader('User-Agent','XMLHTTP/1.0');
x.send('');
while (x.readyState!=4) {WSH.Sleep(50)};
WSH.Echo(x.responseText);
Here's an example first.bat that will sort the fetched values, set low to the lowest value, and set high to the highest.
#echo off
setlocal enabledelayedexpansion
for %%x in (
"http://10.0.0.1/foo/vars.txt"
"http://10.0.0.1/bar/vars.txt"
"http://10.0.0.1/baz/vars.txt"
"http://10.0.0.1/qux/vars.txt"
"http://10.0.0.1/corge/vars.txt"
) do (
set low=
for /f "delims=" %%I in ('fetchvalue.bat "%%~x" ^| sort') do (
if not defined low set "low=%%I"
set "high=%%I"
)
echo low: !low!
echo high: !high!
)
Your inner batch file is ending by setting an environment variable named top: set top=%val1%. You'll need to change that to set val1=%val1%.
...
echo !val1!
ENDLOCAL & SET val1=%val1%

Howto add a string to the 'type <filename>' DOS command before merging into file?

Question: I've several text files containing sql create table/column/view/storedProcedure textfiles. Now I want to merge the textfiles into one textfile.
I go into the directory, and type:
type *.sql >> allcommands.sql
Now to problem is I should add the text ' GO ' after every file's content.
I can append Go by doing
type *.sql >> allcommands.sql & echo GO >> allcommands.sql
But this only inserts go once.
How can I accomplish this with DOS commands ?
You want something like this:
for %%f in (*.sql) do type %%f >>allcommands.sql & echo GO >> allcommands.sql
The %% is for use in a batch file. If you're not running it from a batch file you only need single % signs.
Try this one
for %%f in (*.sql) do (
type %%f >>allcommands.sql
echo. >> allcommands.sql
echo GO >> allcommands.sql
echo. >> allcommands.sql )
it adds newline then go for each SQL file. it works for me try it.
Use copy to concatenate the first file with a file with "GO" text, then concatenate again with the second file.
#echo off
CLS
::concat.bat outfile.sql
setlocal EnableDelayedExpansion
If EXIST GOTMP.TMP DEL /Q GOTMP.TMP
Echo GO>GOTMP.TMP
ECHO.>>GOTMP.TMP
If EXIST "%~1" DEL /Q "%~1"
Echo.>"%~1"
for /f "tokens=*" %%A in ('dir /a-d /on /b "*.sql"') do call :perfaction "%%A%" "%~1"
ECHO Done Generating Output "%~1"
ECHO.
pause
Goto :EOF
:perfaction
ECHO "%~1"
copy "%~2"+"%~1"+GOTMP.TMP "%~2"
GOTO :EOF