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.
Related
So I'm trying to make a search engine that, when you input a search string, replaces the spaces with a "+", and it'd be helpful if someone pointed out which commands I can use to achieve that.
So far I haven't found anyone that has the same question, which is why I'm posting it here. I've found someone with a way to detect spaces in a variable:
if not "%VAR%"=="%VAR: =%"
but no way to replace them.
Any hints?
P.S.: Please, do not recommend me PowerShell or other scripting languages/methods like I saw some people do, I have my reason for using batch and I'm going to stick to it.
So let me explain how substitution works.
set "var=This is a line with spaces"
set "var=%var: =+%"
echo %var%
in the second set we set var to %var% again, but we use substitution of spaces. Everything after : up to = is the search function and everything after = up to the % is the replace function. So %var: =+% means find all the space and replace with + Hence the outcome of the above code will be:
This+is+a+line+with+spaces
Obviously the variable can be manipulated multiple times:
set "var=This is a line with spaces"
set "var=%var: =+%"
set "var=%var:spaces=pluses%
echo %var%
you can also use the substitution to do comparisons without doing substitution using set:
set "var=This is a line with spaces"
if /i "%var: =+%"=="This+is+a+line+with+spaces" echo Matched!
I suggest you read the help by running set /? from cmdline.
This is how I have always remembered processing the CONTENTS of a file line-by-line in a batch file (backed up by web search):
for /F "delims=" %%N in ("del files.txt") do del "%%N"
It now deletes "del files.txt" and #echo %%N gives "del files.txt"
Does it have something to do with the name needing to be quoted because of the space? WTF am I missing?
("string") is used to parse strings. ("filename") can be used with usebackq. It seems you confused them in your search. So, you can write:
for /f "usebackq delims=" %%N IN ("del files.txt") do whatever you want.
Please don't accuse me of not reading help.
for /? (first thing I did) yields:
FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ('string') DO command [command-parameters] MAKE NOTE THAT 'string' IS IN SINGLE QUOTES!!!
FOR /F ["options"] %variable IN (command) DO command [command-parameters]
because I just happened to lose the "if usebackq..." line because it just happened to get lost coinciding withe the "press any key..." line in my command prompt window because it just happened to be sized unfortunately (and still doesn't show file-set in standard quotes).
I was asking why quotes wouldn't be used in (file-set) when they are required for spaces and used in (file-set) without /F (i.e. for \%f in ("c\:path w spc\*.txt") do...)
I have used that exact syntax in other working batch files. though I went and checked an in each case, %1 or an environment var were in () which apparently settled how quotes were addressed.
#1 google search result: ss64.com/nt/for_f.html which in my frustration I misread the usebackq in reverse and tried ` because it went on to say
"The backquote character ` is just below the ESC key on most
keyboards"
, indicating to me that I was supposed to use that (once or twice) as quotes as seems rational to me if I'm giving direction to use that character.
I am providing this clarification in case it helps others experiencing my frustration.
Those who have "graded me down" for what I believe is legitimate confusion by doing so also prevent me from asking a different question in a totally unrelated area and I would appreciate if they would re-evaluate. I have certainly learned my lesson about unfortunate series' of events.
I understand the reasons that underlie the policy but am very frustrated that 1 time in the years I have been a member being criticized, just for poor luck IMHO, for a question should penalize me apparently 4 or 5 days.
(It's also confusing since since the message says
It's been 2 days since you asked your last question. We ask that you wait 2 days before asking again. Use this time to revisit your previous questions, editing to address any issues that folks have pointed out in comments.
Does that mean 2 more days or the two I have waited?)
So I guess if people want to pound on me for this protest, how many more days can it cost me?
And a further Thanks! to double-beep for the useful answer even if it wasn't a complete explanation.
Well, back to the penalty box...
I am dealing with some code that was put together by someone who has long since left the company. It reads:
REM XX.XXX YYYYMMDD Author Description
REM version=4.3 &:20170418 comment comment comment
REM version=4.4 &:20170519 comment comment comment
SET version=4.5c &:20170604 comment comment comment
SET "version=%version: =%"
After puzzling through this, we finally figured out two things: one, that the & thing works to tell DOS that a new command is coming in the same line, and then the :date just gets thrown out because DOS doesn't know what to do with it.
But then we get to this SET "version=%version: =%" nonsense.
All I've been able to deduce from it so far is that it will remove spaces, so that if I did this instead:
SET version=4.5 c
SET "version=%version: =%"
ECHO %version%
I'll get "4.5c" echoed to the screen.
I can't find any information about this ": =%" business anywhere online. Is there a good reason to be doing this?
What Is Going On?:
This looks like Variable Edit/Replace or in other terms syntax-replacement. What this allows you to do is take a string, and replace characters or words from it and either replace the existing string or create a new modified one.
Taking example SET "version=%version: =%" This will be modifying the string version and removing all spaces from the string.
Positives To This Method:
Being that some strings or code need to be modified, you can very conveniently use a pure batch option to replace words in text files, remove words from string, add commas after words, and even remove the last x characters in a string.
syntax-replacement is commonly used for issues that that cannot be solved within a for loop or strings that need to be tweaked before being used, an example will be folder paths. In for loops, when processing strings containing \ and trying to use the delims=\, you sometimes need to change it to a less conflicting character as ; - SET "String=%String:\=;". The uses are endless.
Negatives To This Method:
This is a very easy way to edit strings but can come with a negative being that you cannot edit strings with special characters without first using an ^ to escape special characters in the base string. An Example of this will be the following:
SET "version=Hello & There" - This will break the syntax-replacement code as &
is calling a new command.
SET "version=Hello ^& There" - This is the proper way to "ignore" the & symbol
for processing.
Check out Set /? in a CMD window for more information.
I have a batch script running in windows. Every time the batch script is invoked an input path is provided as a parameter. I need to extract the folder name from the path.For that i need to get the last index of "/" from the path and then take a substring from that path until the end of the string.
Suppose I have a string /home/home1/home2/home3
The output I require is home3. Is there any way to extract the same.
For plain DOS/Windows batch files, this should work:
set FILE="c:\foo\bar.txt"
for /F %%i in ("%FILE%") do #echo %%~ni
That comes from DOS BAT file equivalent to Unix basename command?
Windows PowerShell and the Unix shell offer other alternatives.
So you have a string representing a folder path, and you want the name of the right most folder within the path. CMD.EXE provides convenient tools to work with file/folder paths, so there is no need to search for the last \.
You don't state where the string resides. Most likely it is either 1) in a batch parameter from a CALL to a batch script or :function, or 2) within an environment variable. I will assume a parameter, and show a succession of solutions, each one better (more robust) than the prior one. At the very end I will show a slight twist to adapt to working with an environment variable.
So if parameter %1 contains /home/home1/home2/home3, then all you need is %~n1.
But folder names can include dots, and the text after the last dot is considered to be an extension. So you need the x modifier as well to include the extension. For example, if %1 contains /home.1/home.2/home.3, then %~nx will yield home.3. It works just as well if there is no extension.
But folder names can include a poison character like &, so you should enclose the string in quotes: "%~nx1". If you are assigning the result to a variable, then you should enclose the entire assignment in quotes: set "folder=%~nx1". The value will not include the quotes, so be sure to add quotes when expanding the variable: "%folder%", or else use delayed expansion !folder!.
But sometimes people include a trailing backslash when passing a folder path, as in \home1\home2\home3\. The trailing backslash positively indicates that the path is to a folder, but %~nx1 will yield nothing. There is a simple trick using a FOR loop and an appended dot to solve this.
for %%F in (%1.) do set "folder=%%~nxF"
Note that FOR variables use the exact same modifiers as parameters. The appended dot elegantly solves the problem in a tricky way. If there is a trailing backslash, then the dot represents the "current" directory from that postion. The expansion modifiers automatically normalize the result into a canonical form, which yields the correct answer. But it also works if there is not a trailing backslash. File and folder names are not allowed to end with a dot or a space, and the expansion normalization will strip the trailing dot.
There are a few other esoteric cases dealing with UNC paths and long paths that are solved by adding the ~f modifier to convert %1 into the full canonical path.
Here is the ultimate solution that should "always" work with batch parameter %1.
for %%F in ("%~f1.") do set "folder=%%~nxF"
I put the word "always" in quotes because it is possible for the code to fail, but it would require the end user doing something stupid like passing "c:\This"^&"that\". In this case, the correct thing to do is simply pass "c:\This&that\".
Note that the passed path could be the root of a volume, like "c:\". In this case the result is an empty string, which is correct - there is no folder name.
How to work with an environment variable instead
Suppose you have variable folderPath that contains the path string. If you know that the value does not contain any quotes, and it is not a UNC or long path, then you can simply use:
for %%F in ("%folderPath%.") do set "folder=%%~nxF"
But that can fail in multiple ways if the value already contains quotes, or if it is a UNC or long path. The solution is to add an extra FOR /F loop coupled with delayed expansion to safely transfer the value into a FOR variable. Then the ~f modifier can be used as before. But paths can include the ! character, and FOR variable expansion will strip any ! if delayed expansion is enabled. So delayed expansion must be strategically toggled on and off.
Here is the ultimate solution for working with a variable
I'm assuming that delayed expansion is currently off.
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%A in ("!folderPath!") do (
endlocal
for %%F in ("%%~fA.") do set "folder=%%~nxF"
)
I'm not aware of any scenarios where this last code can fail.
I have the following entry in the file Build.aip. I need to write a batch file that searches for "PackageFileName and prints the value assigned for that in the file. In this case, I need to print MyPackageName on the console:
<ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="C:\Build\Build.aip" PackageFileName="MyPackageName" Languages="en" InstallationType="4">
May you please give me some examples how I can do that? I seen in some forums that this can be done using FINDSTR.
Thanks in advance.
findstr "PackageFileName" Build.aip
If you want to make it case insensitive, add the /i argument.
For more details, type findstr /?
Updated for an example to use the for statement
FOR /F "token=2" %i in (`FINDSTR "PackageFileName" Build.aip`) do SET var=%i
A couple things to keep in mind here:
This version is based on Windows 8.1; it may work differently in different versions of Windows.
The token=2 is an example assuming that the word you are looking for is the second word in the line
If PackageFileName appears more than once in Build.aip, this code will break.
The findstring command is surrounded by back-ticks, not single quotes.
I haven't tested it; the SET may not actually survive the for loop. So test!
If you use it in a batch file, you must double all the % signs.