How to make sure date/time syntax is correct in batch script - batch-file

I have a line in a batch file that renames a file with a date and time appended to it.
rename "C:\Program Files (x86)\File Directory\sub directory\logs\Backups\Client.txt" Client%date:~7,2%%date:~4,2%%date:~10,4%%time:~0,2%%time:~3,2%%time:~6,2%.txt
This works fine, except if the first time parameter (%time:~0,2%) is a single digit. It will error with an incorrect syntax command. I understand why it occurs (there's a similar post here) but can't seem to get the correct syntax to make the command run successfully when the hour parameter is a single digit (between 01-09).
What command syntax do I need to add to make sure the command works with single digits for the hour ?

set hour=%time: =0%
rename "C:\Program Files (x86)\File Directory\sub directory\logs\Backups\Client.txt" Client%date:~7,2%%date:~4,2%%date:~10,4%%hour:~0,2%%time:~3,2%%time:~6,2%.txt

Related

Escape characters of a file path argument for a batch file

I was making a batch file to take dragged-and-dropped folders for program input. Everything was working fine until I passed a folder, which for the sake of this post, called foo&bar.
Checking what %1 contained inside the batch file looked like C:\path\to\foo or C:\path\to\foo\foo. If the file path were in quotes it would work, so the only working code that slightly takes this into effect is :
set arg1=%1
cd %arg1%*
set arg1="%CD%"
Which changes directory to the passed argument using wildcards. However this only works once for if there is another folder with un-escaped characters inside the parent folder, passing the child folder would result in the parent folders' value.
I tried the answer of this post, which suggests to output the argument using a remark and redirection statement during an #echo on sequence. However no progress occurred in rectifying the problem. Any suggestions?
To recap, I am looking for ways to pass folders with un-escaped characters as arguments to a batch file. The implementation should preferably be in a batch file, but answers using VBScript are welcome. However the starting program must be in batch as this is the only program of the 3 that accepts files as arguments.
To test this, create a batch file with following code:
#echo off
set "arg1=%~1"
echo "the passed path was %arg1%"
pause
Then create folders called foobar and foo&bar. Drag them onto the batch file to see their output. foo&bar will only return C:\path\to\foo.
OK, so the problem is that Explorer is passing this as the command line to cmd.exe:
C:\Windows\system32\cmd.exe /c ""C:\path\test.bat" C:\path\foo&bar"
The outermost quotes get stripped, and the command becomes
"C:\working\so46635563\test.bat" C:\path\foo&bar
which cmd.exe interprets similarly to
("C:\working\so46635563\test.bat" C:\path\foo) & bar
i.e., bar is considered to be a separate command, to be run after the batch file.
The best solution would be to drag-and-drop not directly onto the batch file but onto, say, a vbscript or a Powershell script or a plain old executable. That script could then run the batch file, either quoting the argument appropriately or putting the directory path into an environment variable rather than on the command line.
Alternatively, you can retrieve the original command string from %CMDCMDLINE% like this:
setlocal EnableDelayedExpansion
set "dirname=!CMDCMDLINE!"
set "dirname=%dirname:&=?%"
set "dirname=%dirname:" =*%"
set "dirname=%dirname:"=*%"
set "dirname=%dirname: =/%"
for /F "tokens=3 delims=*" %%i in ("%dirname%") do set dirname=%%i
set "dirname=%dirname:/= %"
set "dirname=%dirname:?=&%"
set dirname
pause
exit
Note the exit at the end; that is necessary so that cmd.exe doesn't try to run bar when it reaches the end of the script. Otherwise, if the part of the directory name after the & happens to be a valid command, it could cause trouble.
NB: I'm not sure how robust this script is.
I've tested it with the most obvious combinations, but YMMV. [It might be more sensible to use delayed expansion exclusively, I'm not sure. It doesn't seem to be necessary except in the first set command. Jeb's answer here might be a better choice if you're going this route.]
For the curious, the script works like this:
Load the original command line into dirname [necessary for the reason pointed out by jeb]
Replace all the & characters with ?
Replace all the quote marks with *
If a quote mark is followed by a space, suppress the space.
NB: it is necessary to suppress the space to deal with both the case where the path contains a space (in which case Explorer adds quote marks around it) and the case where it doesn't.
Replace all remaining spaces with /
NB: ? * and / are illegal in file names, so these replacements are safe.
At this point the string looks like this:
C:\Windows\system32\cmd.exe//c/**C:\path\test.bat**C:\path\foo?bar**
So we just need to pull out the third asterisk-delimited element, turn any forward slashes back into spaces and any question marks back into ampersands, and we're done. Phew!

Batch File Command throwing error in loop

Here is the situation. I need to "type" a .sj files content, then save it as an .js file. This is not the same as a rename, as the encoding is different. I am very new to Batch File syntax, but proficient with other programming languages. Here is what I have tried:
call for %%i in (.\*.js) do type %%i > %%i.js
But this is giving me the "%%i is unexpected at this time" Error.
If you need me to provide more insight, I will be happy to.
BACKGROUND: Trying to use JSDoc3 on .sj files but the encoding is not compatible. Using an encoder did not work either. What did work is copying and pasting the contents into a new file with encoding UTF8. But like I stated, a program like UTFCast did not work.
Two percent signs without anything in between (in a batch file) are treated like a single percent sign in a command (not a batch file).
Moreover CALL command enables a user to execute a batch file from within another batch file.
So from cmd you need to run only below..
for %i in (.\*.js) do type %i > %i.js
if you want to learn more...
for command
call command

Wildcards and the MOVE command in a batch file - Wildcard not recognised as such

I have a batch file with the following line in it:
move d:\cdr\C0*.%yyyy%-%mm%-%dd%*.csv d:\CDRArchive\%yyyy%%mm%\
where the variables yyyy mm and dd are for their resective parts of a given date. When I run this, the batch file parses the variables out correctly, but I doesn't recognise the wildcard character *, so I get the following line:
> move d:\cdr\archive\C0*.2013-09-08*.csv d:\CDRArchive\201309\
A duplicate file name exists, or the file
cannot be found.
Any help is much appreciated.
It works fine, once the target folder is created. Note that the error message you supplied shows that the filespec is wrong or the folder is wrong. The error message you get when they are right is shown below. (tested in Windows 8)
d:\>move d:\cdr\C0*.2000-10-01*.csv d:\CDRArchive\200010\
Cannot move multiple files to a single file.
d:\>md d:\CDRArchive\200010\
d:\>move d:\cdr\C0*.2000-10-01*.csv d:\CDRArchive\200010\
d:\cdr\C0abc.2000-10-01.aaa.csv
d:\cdr\C0abc.2000-10-01.bbb.csv
d:\cdr\C0abc.2000-10-01.ccc.csv
3 file(s) moved.

My batch script is reporting an error stating "was unexpected at this time"

The Windows batch file I am trying to run contains the following assignment:
set ANT_HOME="C:/Program Files/apache-ant-1.8.4"
The offending line is:
call %ANT_HOME%/bin/ant -f ../config/common.xml start_db
And when I run the script with echo on I get:
call "C:/Program_Files/apache-ant-1.8.4"/bin/ant -f ../config/common.xml start_db
Files/apache-ant-1.8.4""=="" was unexpected at this time.
I've moved the second quote to to the end of the path, after the ant, but I receive the same error message.
If ant were an .exe I would say your code should work. But I suspect that ant is a batch file, and the error is occurring within the ant script.
I base my conclusion on your error message - specifically the following portion of it: ""=="". The error message is a batch parsing error, and I don't see how your code could generate those characters. So I figure ant must be a batch script that is causing the problem.
I suspect ant.bat has #echo off at the top, so you are not seeing the actual line that is failing.
Not having access to the ant.bat script, I couldn't possibly diagnose exactly what is failing, nor can I guess on how to fix it.
Update - exact problem found
I found a copy of ant.bat online.
It has the following line of code within:
if "%ANT_HOME%"=="" set ANT_HOME=%DEFAULT_ANT_HOME%
Your definition of ANT_HOME includes enclosing quotes, so the code is trying to execute
if ""C:/Program Files/apache-ant-1.8.4""=="" set ANT_HOME=%DEFAULT_ANT_HOME%
The space is not quoted, and you have your error.
All you need to do to fix everything is to remove the quotes from the definition of ANT_HOME, and then add quotes to your CALL statement:
set "ANT_HOME=C:/Program Files/apache-ant-1.8.4"
call "%ANT_HOME%/bin/ant" -f ../config/common.xml start_db
Forward-slashes are not always reliable as folder delimiters within Windows. See Why does the cmd.exe shell on Windows fail with paths using a forward-slash ('/'') path separator?.
Better to use back-slashes.
set "ANT_HOME=C:\Program Files\apache-ant-1.8.4"
call "%ANT_HOME%\bin\ant" -f ..\config\common.xml start_db
The quotes have to completely surround a file name. You can't use them for partial names. Try this instead:
set ANT_HOME=C:\Program Files\apache-ant-1.8.4
call "%ANT_HOME%\bin\ant" -f ../config/common.xml start_db
Oh, and I changed some of your slashes to backslashes (DOS doesn't like forward slashes). I assume you are allowed to use / in that parameter you are passing though.

Stupid Batch File Behavior. Tries to execute comments

I have tried prefixing lines with semicolons, 'REM', etc.. but no matter what when I run my batch file I keep getting "unknown command REM whatever"
"REM test" It is not recognized, and it is windows vista. I simply get "rem" output back to my console.
That's entirely normal behavior. Batch files are simply sequences of commands that are run one after another. So every line will get output to the console as if it were typed there.
H:\>echo rem test > test.cmd
H:\>test
yields the output
H:\>rem test
as if I typed rem test directly to the console.
You can suppress this by either prefixing the line with #:
#rem test
or by including echo off in the batch file:
#echo off
rem test
If I put ":: test" and execute it I get back "Test".
Can't reproduce here.
If I put "; test" it recursively executes itself
A semicolon at the start of the line seemingly gets ignored.
If you're talking about cmd.exe batch files under Windows, you can use:
rem this method or
:: this method.
For bash and a lot of other UNIX-type shells, you use:
# this method.
I'm pretty certain you're not using cmd.exe since that would give you an error like:
'rem' is not recognized as an internal or external command,
operable program or batch file.
rather then:
Unknown command ...
If you are using a UNIX-type shell, the # character is almost certainly what you're after. If you let us know exactly the shell you're using, we can probably help out further.
you probably created an UNICODE file. These files contain 2 bytes header named BOM
which is not shown by any editor but cmd attempts to execute them and fails.
To make sure this is indeed an issue: type any other command at the very beginning
of your file and see it throws the same error - for example #echo test
To fix it, just create a new plain text file and copy content of the original file there.
then remove the original file and replace it by the newly created one.
In my case the problems are line endings. Somehow Maven or the Jenkins pipeline running on a Linux machine changed the line endings from Windows style (CR LF) to Unix style (LF). Changing them back solves the issue for me.

Resources