i use this script to compress all .txt and .cpi files into the backup folder in separated files with 7zip. After the files are zipped i delete the original files. However this script has a logical flaw. Lets say if the 7zip program fails to run, the files will also get deleted. How can i change the script so that it should not delete the files if they don't get zipped first. Also how can i change this script so it zips files that are older than 7 days? Thanks for your help.
#echo off
setlocal
set _source=C:\test7zip\bak
set _dest=C:\test7zip\bak
set _wrpath=C:\Program Files\7-Zip
if NOT EXIST %_dest% md %_dest%
for %%I in (%_source%\*.txt,%_source%\*.cpi) do "%_wrpath%\7z" a "%_dest%\%%~nI.7z" "%%I" & del "%%I"
pause
You seem to now more than me but i might be able to help....
Inside the 7zip you could a batch file that when unzipped changes a system varible...
The batch file (that you have already done) that unzips the files could check to see if variable is true before delete the files .... or something.?
Hope that helps in anyway?
For the zipping of the files witch are a certain days old... you could have a batch file that has a 7 day timer and that after the time is up it zips the certain directory of files into 7zip?
That's all i could help you with.
I didn't check or test your code thoroughly, but I did notice this right away. The "&" in the last line of your script creates a conditional command that will always execute the second command, regardless whether the 1st fails or succeeds. Change it to && to create a conditional command where the 2nd command only executes upon successful completion of the 1st, like this:
for %%I in (%_source%*.txt,%_source%*.cpi) do "%_wrpath%\7z" a "%_dest%\%%~nI.7z" "%%I" && del "%%I"
For including files older than 7 days, use the below changes to move them to a temp directory before zipping them:
set _source=C:\test7zip\bak
set _dest=C:\test7zip\bak
set _temp1=C:\test7zip\temp1
set _wrpath=C:\Program Files\7-Zip
if NOT EXIST %_dest% md %_dest%
forfiles /P %_source% /S /M *.txt /D -7 /C "cmd /c move #file %_temp1%"
forfiles /P %_source% /S /M *.cpi /D -7 /C "cmd /c move #file %_temp1%"
for %%I in (%_temp1%\*.txt,%_temp1%\*.cpi) do "%_wrpath%\7z" a "%_dest%\%%~nI.7z" "%%I" && del "%%I"
Related
1.bat - does as expected: go to the temp folder, do something, return to the original folder. The current working directory (cwd) is the same before and after running 1.bat.
2.bat - when the 'do something' is running the handlebars nodejs package, even when it only prints something, after exiting the batch file, cwd changes.
3.bat - not using PUSHD, POPD. Same as 2.bat.
When running the similar in shell scripts, cwd never changes.
The question: what is wrong? How to go back to the original cwd?
REM 1.bat
PUSHD %CD%
CD /D %TEMP%
DIR
POPD
REM 2.bat
PUSHD %CD%
CD /D %TEMP%
handlebars --help
POPD
REM 3.bat
SET orgdir=%CD%
CD /D %TEMP%
handlebars --help
CD /D %orgdir%
As you indicate, this works
REM 1.bat
PUSHD %CD%
CD /D %TEMP%
DIR
POPD
but it is not how this should be written.
pushd works by saving the current active directory (to be later retrieved by the popd) and then change to the indicated one, changing the drive unit if needed and if necessary mapping a drive letter when changing to a UNC path.
paths should be quoted to avoid problems with spaces or special characters
So, the code should be
REM 1.bat
PUSHD "%temp%"
DIR
POPD
Now, the problematic batch file could be
REM 2.bat
PUSHD "%temp%"
handlebars --help
POPD
but, if the original file didn't return to the previous active directory, this will also fail to do it.
Why? in windows handlebars command is a batch file. When a batch file invokes another one, the execution flow is transfered to the called file and does not return to the caller, so, the popd will not be executed.
To invoke a child batch file and get the execution flow return to the caller, you will need to use the call command
REM 2.bat
PUSHD "%temp%"
call handlebars --help
POPD
Another alternative in this case (if you don't need to end with changes in any environment variable nor continue executing commands in the caller) is to use the setlocal command. It saves a copy of the current environment to allow us to discard any change made to it when calling the endlocal command or when the batch context ends. This save operation includes the current active directory.
REM 2.bat
setlocal
cd /d "%temp%"
handlebars --help
Now, the execution flow does not return to the caller, but it is not needed. When the child batch file (handlebars) ends, the batch context is released and the changes to the environment after the setlocal are reverted.
In my project I have got following post-build Event:
xcopy "$(TargetDir)Data" "$(ProjectDir)Data" /Y /I
After the run has ended the program copies the files. But if in TargetDir/Data is a complete NEW file, this event does not copy the new file to ProjectDir/Data.
but I would like to have this new files copied to TargetDir/Data. How do I achieve this?
Thanks for help!
"Data" sounds like a directory, not a file. You'll have to create it first. You also appear to have reversed the arguments. Fix:
if not exist "$(TargetDir)Data" mkdir "$(TargetDir)Data".
xcopy "$(ProjectDir)Data\*.*" "$(TargetDir)Data" /Y /I /D
If you in fact meant to copy back to the project directory, very unusual, then just swap TargetDir and ProjectDir in the above snippet.
I want to create a bat file that will search for xml files from a folder and if one xml file is older than 10 days to show a pop-up message.
The idea is that I don't know how exactly I can do this with if and else.
I know that I can use
forfiles /p "path" /s /m *.xml /d -10 /c "cmd /c echo #file"
for searching the date for the xml files but how to show the message just in case one of the xml is older than 10 days ? In the other case no message.
This uses your forfiles command - it just changes it to require an enter when the file is echoed
#echo off
forfiles /p "path" /s /m *.xml /d -10 /c "cmd /c set /p var=#file"
exit
I have many excel files that I need zipped into each of their own zip folders. I thought I had this ironed out, but I have co-workers coming back to me saying that they cannot open the excel file because it has become corrupted. I went back and checked the original file, and it opens up just fine. But when I open up the same version of the file that was zipped, I too get the corrupted error. I'm on Office 2010, which is able to repair it, but my co-workers are all Office 2007 which does not seem to be able to fix the file. My batch code is as follows:
for /r %%X in (*.xlsm) do "C:\Program Files\7-Zip\7z.exe" a -tzip "%%~nX" "%%X"
I think you might be using a wrong value as the first parameter to the 7zip executable. According to the documentation on FOR:
%~nI - expands %I to a file name only
And according to the 7zip documentation:
You can use the "a" command with the single letter a. This command stands for 'archive' or 'add'. Use it to put files in an archive. You have to specify the destination archive, and the source files (in that order).
So, using your script with an example file, it seems to me that your command line becomes:
"C:\Program Files\7-Zip\7z.exe" a -tzip "somefile.xlsm" "C:\path\to\somefile.xlsm"
Shouldn't the first parameter have a .zip file extension on the end? So the line is modified to look like this:
for /r %%X in (*.xlsm) do "C:\Program Files\7-Zip\7z.exe" a -tzip "%%~nX.zip" "%%X"
As annoying as it is, file extensions actually mean something in Windows. Your previous line was creating a zip file with the .xlsm extension. When people try opening those files, Excel complains (because it's a zip file; not a .xlsm).
#Echo OFF
PUSHD "C:\Program Files\7-Zip" && (
FOR /R "%CD%" %%# in (*.xlms) DO (7z a -tzip "%%~n#.zip" "%%#")
POPD
)
REM Don't worry about the PUSHD command, the %CD% variable isn't expanded, that's the trick.
Pause&Exit
And you can use the dynamic operator * (asterisk) and 7zip -recursive parameter if you want all together in one file:
7z a -r -tzip "ALL.zip" "*.xlsm"
Sorry guys.
It was a false alarm. Turns out it wasn't all of the files, but only a select few. The files were sectioned out by region, and the only ones that were corrupt were the first region. Why? I can only assume that they were corrupted by my original attempts at making a batch file, as all the other files were zipped with the finished batch and thus didn't have errors. So nothing was wrong with my script. Thanks for the help though.
I have checked out few files on the perforce client.
I can get the list of those files by command 'p4 opened'
It gives path in the form of //depot/... like
I want to know how this can be converted to path on the local path(I mean client path)
So that i can create a batch file to backup those just before end of the Day
Thanks In advance
Uday
This batch script can zip files into individual change list.
for /F "tokens=1,5,6 delims=# " %%a IN ('p4 opened') do for /F "tokens=3" %%j IN ('p4 where %%a') do zip %%b%%c %%j
It will create files like this:
change571620.zip
change673450.zip
change723098.zip
defaultchange.zip
You can use p4 where to convert depot filespecs into local filespecs.
To parse the output of p4 where from a Windows batch file, something like the following might help:
for /f "tokens=3" %%i in ('p4 where %my_depot_filespec%') do echo %%i
Note that the body of the for-loop may execute more than once for more complex mappings, such as the ones described in the p4 where documentation. If you need to handle those, you might need to do more complicated parsing.
You also might want to consider why you feel the need to back up files at the end of each day oustide of using Perforce itself.
You may find that using a development branch and submitting the changes (with the "reopen for edit" flag checked) at the end of each day is actually easier and better. For a start, you are then using Perforce to keep track of your changes, rather than your own manual system.
Using a development branch means that you can do these checkins without risk of messing up your workmates.
Just a suggestion worth considering, that's all.
p4 where filename
This is the command you're looking for.
It will list the depot path, client path and absolute path of the file on the local file system. Just pipe the output into cut and pick the absolute path and copy them over.
This batch script can zip files into individual change list.
for /F "tokens=1,5,6 delims=# " %%a IN ('p4 opened') do for /F "tokens=3" %%j IN ('p4 where %%a') do zip %%b%%c %%j
It will create files like this:
change571620.zip
change673450.zip
change723098.zip
defaultchange.zip
Check your p4 client as there you have defined the mapping for //depot to your filesystem path. Replace //depot with that to get a local path for a file so that you can backup.
I don't know how you can get that programmetically in a batch file.
Following BAT script copies the perforce open files from a pending changelist
(%1 command line argument)
p4 opened -c %1 > open-%1.txt
for /F "tokens=1 delims=#" %%i IN (open-%1.txt) do call :add-to-zip %%i
:add-to-zip
for /F "tokens=3" %%j IN ('p4 where %1') do zip [zip-file-name] %%j
FYI, as of v2012/2013, you'd be better off using Perforce's shelving feature for your daily backup operation. Other users in your team would then be able to access these shelves as well. Using it for backup this way prevents your history from being polluted by intermediate file variants that you don't really care about (or portions of which are not appropriate for checkin).
Thanks a ton :-) Was just searching for the command which can give me the client path of the opened files exactly for the same reason of backing up the files. Not just I got the command, but the script too :-)