During the course of a batch file, a path like the following is stored in temp.txt:
c:\folder1\folder2\.
The period at the end is just because the path is generated from a for /r %%a in (.) statement. I try to get rid of this using the world famous jrepl.bat search and replace batch file, escaping the backslash with a double-backslash:
type temp.txt|jrepl "\\." "" >temp2.txt
Only problem is that this produces strange results because the search string is interpreted as a regular expression instead of a literal string. So then I tried this as instructed by the jrepl documentation:
type temp.txt|jrepl "\\." "" /l >temp2.txt
...but then for some reason nothing changes. The trailing \. at the end of the URL unfortunately remains intact. I have no idea what I'm doing wrong...
Just answered my own question. Once I added the /l option, I no longer needed to escape the backslash, so what works ends up being:
type temp.txt|jrepl "\." "" /l >temp2.txt
Almost deleted this whole question but figured maybe 2 more people might encounter this issue over the next 750 years, so what the heck.
I have tried creating a batch file that moves mods from the gta v directory to another when i need to play online. I wrote this so far:
move E:/Epic Games/GTAV/TrainerV.asi C:/Users/example/Desktop
I got this error:
The syntax of the command is incorrect.
Can someone tell me how to do it right? I would appreciate it.
To be able to operate with any file with a space in cmd/batch, you need to group them with quotes "" and since
E:\Epic Games\GTAV\TrainerV.asi
^ Here
has spaces, you need to surround it with quotes. A good practice is to have quotes anyways. The correct syntax is:
move "E:\Epic Games\GTAV\TrainerV.asi" "C:\Users\example\Desktop"
You have multiple issues with your current command.
First, paths containing spaces must be surrounded in double quotes.
Second, Windows uses the backslash \ instead of the forward slash / as the path separator. While the forward slash might be accepted in some cases, it won't work in all, so it's better to use the proper \.
The corrected version of your code would be
move "E:\Epic Games\GTAV\TrainerV.asi" C:\Users\example\Desktop
Using bq tool I have no problem escaping the > operator with a caret ^:
bq query "SELECT x FROM [presentation_dim.dim_events] WHERE event^>1"
However, when I CALL the exact same command through a bat file whe whole thing breaks down.
call bq query "SELECT x FROM [presentation_dim.dim_events] WHERE event^>1"
I understand call is the problem here. I can't remove it, since I need to run additional commands after it (bq extract and gsutil cp). I've tried adaptations of what is shown on Escape user input in windows batch file, to no avail.
What's wrong here?
Thanks in advance.
I suppose bq.cmd itself contains something like this
set param1=%1
set SQL=%~2
python bigQuery.py --%param1% "%SQL%"
So the line set SQL=%1 requires escaping the special characters.
But when you use CALL, the batch parser has an additional phase of escaping but before it also has a phase of doubling all carets!
So your string in call bq query "SELECT x FROM [presentation_dim.dim_events] WHERE event^>1" is converted to
"SELECT x FROM [presentation_dim.dim_events] WHERE event^^>1"
I think there is no solution with only carets to solve this problem.
But you can avoid this by simply defining a variable containing one caret
set "caret=^"
call bq query "SELECT x FROM [presentation_dim.dim_events] WHERE event%%CARET%%>1"
Excuse me. I think there is a confusion here.
When a parameter is enclosed in quotes, it may include special Batch characters with no need to escape they; the only problematic case is when Delayed Expansion is enabled and the parameter include an exclamation-mark or caret. For example, this line works correctly:
bq query "SELECT x FROM [presentation_dim.dim_events] WHERE event>1"
This way, the same line with a CALL command also works correctly:
call bq query "SELECT x FROM [presentation_dim.dim_events] WHERE event>1"
If you escape the greater-than sign this way ^> and don't use CALL, the character passed is the same ^> that is processed as a single > in bq.bat. However, if you use CALL, then the escape is duplicated and ^^> is passed.
Conclusion: Don't escape the > character.
I receive files which names contain spaces and change every week (the name contains the week number)
IE, the file for this week looks like This is the file - w37.csv
I have to write a script to take this file into account.
I didn't succeed in writing this script.
If I do :
$FILE="This is the file - w*.csv"
I don't find /dir/${FILE}
I tried "This\ is\ the\ file - w*.csv"
I tried /dir/"${FILE}" and "/dir/${FILE}"
But I still can't find my file
It looks like the space in the name needs the variable to be double-quoted but, then, the wildcard is not analysed.
Do you have an idea (or THE answer)?
Regards,
Olivier
echo /dir/"This is the file - w"*.csv
or — you almost tried that —
echo /dir/This\ is\ the\ file\ -\ w*.csv
Use a bash array
v=( /dir/This\ is\ the\ file - w*.csv )
If there is guaranteed to be only one matching file, you can just expand $v. Otherwise, you can get the full list of matching files by expanding as
"${v[#]}"
or individual matches using
"${v[0]", "${v[1]}", etc
First of all, you should not use the dollar sign in an assignment.
Moreover, wildcard expansion is not called in an assignment. You can use process substitution for example, though:
FILE=$(echo 'This is the file - w'*.csv)
Note that the wildcard itself is not included in the quotes. Quotes prevent wildcard expansion.
I have a batch file which moves files from one folder to another. The batch file is generated by another process.
Some of the files I need to move have the string "%20" in them:
move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"
This fails as it tries to find a file with the name:
\\myserver\myfolder\file0name.txt
Is there any way to ignore %? I'm not able to alter the file generated to escape this, such as by doubling percent signs (%%), escaping with / or ^ (caret), etc.
You need to use %% in this case. Normally using a ^ (caret) would work, but for % signs you need to double up.
In the case of %%1 or %%i or echo.%%~dp1, because % indicates input either from a command or from a variable (when surrounded with %; %variable%)
To achieve what you need:
move /y "\\myserver\myfolder\file%%20name.txt" "\\myserver\otherfolder"
I hope this helps!
The question's title is very generic, which inevitably draws many readers looking for a generic solution.
By contrast, the OP's problem is exotic: needing to deal with an auto-generated batch file that is ill-formed and cannot be modified: % signs are not properly escaped in it.
The accepted answer provides a clever solution to the specific - and exotic - problem, but is bound to create confusion with respect to the generic question.
If we focus on the generic question:
How do you use % as a literal character in a batch file / on the command line?
Inside a batch file, always escape % as %%, whether in unquoted strings or not; the following yields My %USERNAME% is jdoe, for instance:
echo My %%USERNAME%% is %USERNAME%
echo "My %%USERNAME%% is %USERNAME%"
On the command line (interactively) - as well as when using the shell-invoking functions of scripting languages - the behavior fundamentally differs from that inside batch files: technically, % cannot be escaped there and there is no single workaround that works in all situations:
In unquoted strings, you can use the "^ name-disrupter" trick: for simplicity, place a ^ before every % char, but note that you're not technically escaping % that way (see below for more); e.g., the following again yields something like My %USERNAME% is jdoe:
echo My ^%USERNAME^% is %USERNAME%
In double-quoted strings, you cannot escape % at all, but there are workarounds:
You can use unquoted strings as above, which then requires you to additionally ^-escape all other shell metacharacters, which is cumbersome; these metacharacters are: <space> & | < > "
Alternatively, unless you're invoking a batch file, , you can individually double-quote % chars as part of a compound argument (most external programs and scripting engines parse a compound argument such as "%"USERNAME"%" as verbatim string %USERNAME%):
some_exe My "%"USERNAME"%" is %USERNAME%
From scripting languages, if you know you're calling a binary executable, you may be able to avoid the whole problem by forgoing the shell-invoking functions in favor of the "shell-free" variants, such as using execFileSync instead of execSync in Node.js.
Optional background information re command-line (interactive) use:
Tip of the hat to jeb for his help with this section.
On the command line (interactively), % can technically not be escaped at all; while ^ is generally cmd.exe's escape character, it does not apply to %.
As stated, there is no solution for double-quoted strings, but there are workarounds for unquoted strings:
The reason that "^ name-disrupter" trick (something like ^%USERNAME^%) works is:
It "disrupts" the variable name; that is, in the example above cmd.exe looks for a variable named USERNAME^, which (hopefully) doesn't exist.
On the command line - unlike in batch files - references to undefined variables are retained as-is.
Technically, a single ^ inside the variable name - anywhere inside it, as long as it's not next to another ^ - is sufficient, so that %USERNAME^%, for instance, would be sufficient, but I suggest adopting the convention of methodically placing ^ before each and every % for simplicity, because it also works for cases such as up 20^%, where the disruption isn't even necessary, but is benign, so you can apply it methodically, without having to think about the specifics of the input string.
A ^ before an opening %, while not necessary, is benign, because ^ escapes the very next character, whether that character needs escaping - or, in this case, can be escaped - or not. The net effect is that such ^ instances are ultimately removed from unquoted strings.
Largely hypothetical caveat: ^ is actually a legal character in variable names (see jeb's example in the comments); if your variable name ends with ^, simply place the "disruptive" ^ somewhere else in the variable name, as long as it's not directly next to another ^ (as that would cause a ^ to appear in the resulting string).
That said, in the (very unlikely) event that your variable has a name such as ^b^, you're out of luck.
In batch files, the percent sign may be "escaped" by using a double percent sign ( %% ).
That way, a single percent sign will be used within the command line. from http://www.robvanderwoude.com/escapechars.php
I think I've got a partial solution working. If you're only looking to transfer files that have the "%20" string in their name and not looking for a broader solution, you can make a second batch file call the first with %%2 as the second parameter. This way, when your program tries to fetch the second parameter when it hits the %2 in the text name, it will replace the %2 with an escaped %2, leaving the file name unchanged.
Hope this works!
How to "escape" inside a batch file withoput modify the file**
The original question is about a generated file, that can't be modified, but contains lines like:
move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"
That can be partly solved by calling the script with proper arguments (%1, %2, ...)
#echo off
set "per=%%"
call generated_file.bat %%per%%1 %%per%%2 %%per%%3 %%per%%4
This simply sets the arguments to:
arg1="%1"
arg2="%2"
...
How to add a literal percent sign on the command line
mklement0 describes the problem, that escaping the percent sign on the command line is tricky, and inside quotes it seems to be impossible.
But as always it can be solved with a little trick.
for %Q in ("%") do echo "file%~Q20name.txt"
%Q contains "%" and %~Q expands to only %, independent of quotes.
Or to avoid the %~ use
for /F %Q in ("%") do echo "file%Q20name.txt"
You should be able to use a caret (^) to escape a percent sign.
Editor's note: The link is dead now; either way: It is % itself that escapes %, but only in batch files, not at the command prompt; ^ never escapes %, but at the command prompt it can be used indirectly to prevent variable expansion, in unquoted strings only.
The reason %2 is disappearing is that the batch file is substituting the second argument passed in, and your seem to not have a second argument. One way to work around that would be to actually try foo.bat ^%1 ^%2... so that when a %2 is encountered in a command, it is actually substituted with a literal %2.