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.
Related
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.
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.
I am writing some batch code to simplify a process I have of downloading some files, renaming them, and then copying them to replace the old ones. I'm running into an issue where I have a FOR loop read in a list of files from a directory, then try to modify the filenames.
The filenames all have FLY in the name, and I want to remove all text after FLY. I can't use tokens because the filenames are inconsistent in length, have multiple spaces, and wouldn't have a set number of tokens. I can't use substring because there is not a set number of characters after FLY.
I've tried using the examples at SS64 and also read numerous threads on here but nothing really seems to match my situation.
Here's the code snippet, appreciate if someone can tell me where I'm going wrong:
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "TOKENS=*" %%A IN ('DIR /B ^"%~DP0VFR^"') DO (
SET FILENAME=%%A
SET REMOVETEXT=!FILENAME:*FLY=!
SET NEWFILENAME=!FILENAME:!REMOVETEXT!=!
ECHO !FILENAME! will be renamed !NEWFILENAME!
)
When I insert echos to see what's going on everything works as expected up until the last SET, where somehow the ending result is !NEWFILENAME! is blank.
Hmm. My results were different from yours.
The " in your dir do not need to be escaped.
The problem with your set statement is that it's interpreted as
SET NEWFILENAME=!FILENAME:! + REMOVETEXT + !=!
and since FILENAME: and = are not existing variables, each will be replaced by nothing yielding "REMOVETEXT", not blank as you claim.
The solution is to use a two-stage evaluation of newname
call SET NEWFILENAME=%%FILENAME:!REMOVETEXT!=%%
which is resolved as
SET NEWFILENAME=%FILENAME:current_value_of_REMOVETEXT=%
in a sub-shell.
After cold brew it occurred to me that I might be going about this all wrong and making it more complicated than it needs to be... I decided to try directly renaming the files with wildcards and that actually worked. Didn't even need the FOR loop.
REN "%~DP0VFR\*FLY*" *FLY
No idea why the first (and overly convoluted) solution I tried didn't work, but this does with a lot less code!
I need to create new copies of a single .html file. The file's name is 065.html.
I copied the file into 066.html using the following command:
C:\>copy 065.html 066.html
But I need more. I need to copy up to 090.html
How can I do this? A loop should do this but I don't know the syntax.
I have tried to use the command as shown here,
for /L %%i IN (66,1,90) do copy 065.html 0%%i.html
but I get an error message that says
%%i was unexpected at this time
I have deleted one preceding % signs. It works now.
for /L %i IN (66,1,90) do copy 065.html 0%i.html
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"