I need to save the output of a curl command to a variable. The only issue is that the output contains spaces and the for command splits them on different lines (the output variable only contains the first block of characters).
Code:
for /F usebackq %%I in (`curl "https://api.checkwx.com/metar/cyyz?x-api-key=c6e048117df34d45871ca85e73"`) do set output=%%I
echo %output%
Outputs: {"data":["CYYZ
Instead of: {"data":["CYYZ 221700Z 00000KT 15SM BKN220 05/M11 A3031 RMK CI7 SLP271"],"results":1}
Am I doing anything wrong?
Thank you #jeb your solution works.
In regards to #Compo's answer, I read the official Microsoft online documentation regarding the for command, but couldn't find a solution there.
It seems like the actual problem was with my . I didn't know they were supposed to be quoted and looking at the examples in the documentation, none were. I tried delims= before but the batch file simply crashed upon that command.
Related
I have a file (let's call it version.txt) that contains a version number and some text:
v5.02
Some text explaining
where and how this
number is used
Based on this answer, I use
set /p version=<version.txt
to store the first line of the file in the version variable. Now I'm trying to write a batch script that operates on folders that contain this version number in their name. However, I get unexpected results because something seems to go wrong when I insert the variable in a path. For example, this script
#set /p version=<version.txt
#echo C:\some\folder\%version%\some\file.exe
prints
C:\some\folder\v5.02
instead of
C:\some\folder\v5.02\some\file.exe
What's going on? I have a feeling there are hidden characters of some sort at the end of the text in the variable, because setting the variable by hand to a constant in the script works.
Edit: I'm using Windows 10 with Notepad++ as my editor, if it helps.
I can only replicate your issue, when version.txt uses Unix line endings (LF) instead of Windows (CRLF). for /f is immune to this issue:
for /f "delims=" %%a in (version.txt) do set "verion=%%a" & goto :skip
:skip
echo C:\some\folder\%version%\some\file.exe
goto :skip breaks the loop after reading the first line.
Since everything I tried didn't seem to work, the solution I found in the end is to call the batch script from a Python script. The Python script reads the first line of the version file and passes it as an argument to the batch script. Out of context, it is a bit of an inelegant solution, but in my case the batch script was already called by a Python script, so it's not that terrible.
Here is a minimal example:
version.txt
v5.02
Some text explaining
where and how this
number is used
script.bat
#echo C:\some\folder\release\%1\some\file.exe
script.py
import os
with open("version.txt") as f:
version = f.readline().rstrip()
os.system("cmd /c script.bat %s" % version)
Edit: Following Stephan's comment, I tried to change the line ending in the text file from LF to CRLF and it indeed solves the problem. However, since I don't really have control over everything that writes in that file, the solution above remains the most feasible in my case.
Edit 2: Stephan's answer (with the for loop) is actually a better solution than this one since it avoids having to transfer part of the work to the calling Python script.
Thanks for looking into my question.
I have a batch command to copy the files to remote server and if I run this command from command prompt it ran well.
echo D|xcopy /E /Y ..\Media \\%Win_Machine%\C$\temp\%APP_VERSION%\Media
Whereas if I run the same command through batch file, it says "Invalid number of parameters".
Please help me if I am missing anything here.
Thanks.
echo D|xcopy /E /Y ..\Media "\\%Win_Machine%\C$\temp\%APP_VERSION%\Media"
Invalid number of parameters would indicate that xcopy sees three or more parameters. Since the first two arguments are switches, then it would seem that the final argument is being interpreted as two or more parameters - which would mean that the values of the user-variables would contain separators. Quoting the arguments tells cmd to interpret the string between the quotes as a single entity.
It was resolved. Forgot to post the answer. I see extra spaces being posted %APP_VERSION%. It is working fine now.
anyway, Thanks Magoo for valuable inputs.
So I´ll explain it a bit here.
I need to create a CSV file but setting the file names one by one is a pain so I was thinking of creating a bat file.
So here's what I have figured out, or actually copied and applied.
In my batch file I got the following code :
dir /b > myFiles.txt
Nice and easy it gives me the following result in the text file:
59019694038.jpg
59019694038_1.jpg
59019694038_2.jpg
59019694038_3.jpg
59019694038_4.jpg
59019694045.jpg
59019694045_1.jpg
59019694045_2.jpg
59019694045_3.jpg
bat.bat
myFiles.txt
But to make things even easier to do I'd like to add a ; after each file it finds.
So the result will be like this :
59019694038.jpg;
59019694038_1.jpg;
59019694038_2.jpg;
59019694038_3.jpg;
59019694038_4.jpg;
59019694045.jpg;
59019694045_1.jpg;
59019694045_2.jpg;
59019694045_3.jpg;
bat.bat;
myFiles.txt;
So my question was if anybody could explain me what I'm currently doing and how I could get this result.
You can replace your DIR ... with:
(FOR %%f IN (*.*) DO #ECHO %%f;)>myFiles.txt
That's a lot easier than parsing file and replacing each line.
If you don't want the line breaks, you can adapt LS_DEV's command:
(FOR %%f IN (*.*) DO #ECHO|set /P=%%f;)>myFiles.txt
Here's an alternative answer which hopefully outputs them on a single line:
#(For %%A In (*) Do #Set/P "=%%A;"<Nul)>"..\myFiles.txt"
In this case I have sent the output to myFiles.txt in the parent of the current directory, just so that it isn't included in it's own results. You can optionally change that to an alternative location or have it included in it's own content if you wish.
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.
The following is a batch script that calls mp3splt (a program that splits mp3s http://mp3splt.sourceforge.net/mp3splt_page/home.php) into partitions of 5 mins long.
for /f %%a IN ('dir /b *.mp3') do call c:\PROGRA~1\mp3splt\mp3splt -t 5.0 -o output\#f+-+#n+-+#t %%a
It breaks when the mp3 files contain a space. Can anyone propose a workaround?
for %%a IN (*.mp3) do (
call c:\PROGRA~1\mp3splt\mp3splt -t 5.0 -o output\#f+-+#n+-+#t "%%a"
)
What others are saying here to quote the variable is doubtless correct. That's needed for it to work correctly. But it also is only half the solution.
Your problem here is that dir /b spits out lines of text, each one containing a single file name, like so:
foo bar.mp3
baz gak.mp3
track01.mp3
...
for /f on the other hand is made for reading files or something else (the dir output in this case) line by line ... but it also does tokenizing. That means it splits strings at configurable places into individual tokens.
By default, /F passes the first blank
separated token from each line of each
file. Blank lines are skipped. You
can override the default parsing
behavior by specifying the optional
"options" parameter. This is a quoted
string which contains one or more
keywords to specify different parsing
options. —help for
So you only get the part before the first space of the file name. You can work around that by using
for /f "delims=" in ...
to specify that tokenizing should be done with no delimiters, essentially giving you the complete line each time. But a better way is actually the one I outlined at the start to just use the regular for to iterate over the files. No surprises with spaces in file names there and it actually makes your intent a lot clearer.
I am regularly surprised why people tend to choose a convoluted and wrong solution over a simple, clear and correct one.
You can quote the variable containing the file name:
"%%a"