I'm using a MediaInfo CLI in a batch script and I don't know what the issue is, but I cannot get this command to work if I use a folder path that has spaces in it. I'm not new to batch scripts and have created hundreds over the years. Normally I would think that using double quotes would solve the issue, but I know it's something else related to using the "for /f" command and passing multiple arguments with double quotes. I've tried everything I could think of but still can't get it to work if I'm using a path with spaces. Without spaces it works just fine, just not with spaces.
Please Note that this is not the full batch script and is only a snippet of the offending code. I also changed the double "%%" variables to single "%" to make it easier for testing on the command line.
Also, in my batch script, instead of using "echo" I am outputting to a variable, which is why I must use the "for" command. All of which is irrelevant to this specific issue.
WORKING EXAMPLES
for /f %g in ('C:\MediaInfo.exe "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv"') do echo %g
.
for /f "usebackq delims=" %g in (`C:\MediaInfo.exe "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv"`) do echo %g
.
NOT WORKING EXAMPLES
for /f %g in ('"C:\folder with spaces\MediaInfo.exe" "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv"') do echo %g
.
for /f "usebackq delims=" %g in (`C:\folder with spaces\MediaInfo.exe "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv"`) do echo %g
Both of the "NOT WORKING" commands result in the same error...
'C:\folder' is not recognized as an internal or external command,
operable program or batch file.
The command within the set (that is the parenthesised part before do) of a for /F loop is actually executed by cmd /C, which may remove potential quotes depending on their positions.
For instance, in the command line:
for /f "delims=" %g in ('"C:\folder with spaces\MediaInfo.exe" "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv"') do echo %g
the outer pair of quotes is removed, leaving behind the invalid command line:
C:\folder with spaces\MediaInfo.exe" "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv
If you now add an additional pair of quotes, it will work. You may even escape these quotes not to have to alter any other escaping in case:
for /f "delims=" %g in ('^""C:\folder with spaces\MediaInfo.exe" "--Inform=General;%MenuCount%" "D:\Some Folder\filename.mkv"^"') do echo %g
This question already has answers here:
windows cmd: problems with for /f with a quoted command with quoted parameters
(2 answers)
Closed 5 years ago.
In a batch file I want to set a variable to the one-line output of a program - a task explained in multiple questions and internet ressources.
In my specific task I want to execute the command
"D:\__My Program\___My Program\Folder1\Folder2\..\..\FileVersion\FileVersion\bin\Release\FileVersion.exe" /n "D:\__My Program\___My Program\Folder1\Folder2\bin\Deploy\My Program.exe"
As you can see, the path for the program I want to execute, FileVersion.exe contains spaces, and the second parameter handed to FileVersion.exe contains a full path with spaces as well.
When I call the above command either directly at the command line or by using CALL in the batch file it correctly executes the program prints out the expected output.
Now, to capture the output of executing the program I use the follow batch command
FOR /F "usebackq tokens=* delims=" %%i IN (`"D:\__My Program\___My Program\Folder1\Folder2\..\..\FileVersion\FileVersion\bin\Release\FileVersion.exe" /n "D:\__My Program\___My Program\Folder1\Folder2\bin\Deploy\My Program.exe"`) DO (
echo %%i
)
The FOR documentation says
usebackq Use the alternate quoting style:
- Use double quotes for long file names in "filenameset".
- Use single quotes for 'Text string to process'
- Use back quotes for `command to process`
I think I did this correctly by using back quotes around the command, and using quotes around the filenames.
However, the call fails with the message (translated from German)
The command "D:\My" is either incorrect or couldn't be found.
I think this points to a problem with escaping the spaces.
The weird part: If I either replace the path of the exe to call, or the parameter with a path sans spaces, it works. So both
FOR /F "usebackq tokens=* delims=" %%i IN (`FileVersion.exe /n "D:\__My Program\___My Program\Folder1\Folder2\bin\Deploy\My Program.exe"`) DO (
echo %%i
)
and
FOR /F "usebackq tokens=* delims=" %%i IN (`"D:\__My Program\___My Program\Folder1\Folder2\..\..\FileVersion\FileVersion\bin\Release\FileVersion.exe" /n Test.exe`) DO (
echo %%i
)
work.
Why don't two quote-escaped strings work in the same command and how can I fix it?
I wouldn't use usebackq and first resolve the complex path:
#Echo off
Pushd "D:\__My Program\___My Program\Folder1\Folder2\..\..\FileVersion\FileVersion\bin\Release"
FOR /F "tokens=*" %%i IN (
' FileVersion.exe /n "D:\__My Program\___My Program\Folder1\Folder2\bin\Deploy\My Program.exe" '
) DO echo %%i
PopD
This command does not work it wont accept spaces in the path name and I cant figure out how to fix it please help
for /f "tokens=* delims=" %%x in (E:\NON-school stuff\space space\a.txt) do echo %%x
I have tried everything please help!
Easy fix.
set "sourceFile=E:\NON-school stuff\space space\a.txt"
for /f "usebackq tokens=* delims=" %%x in ("%sourceFile%") do echo %%x
Anytime you have spaces in file paths you need to quote them and if you read the help for the FOR /F command you will see that the usebackq option allows you to use quotes when you have spaces in file names. If you don't use the usebackq option it treats the file name as a string.
one trick is to transform your filename into a short filename, so it may be accepted by any command without problems
for %%a in ("\some dir\some text.txt") do echo %%~sa
in your case
for %%a in ("E:\NON-school stuff\space space\a.txt") do for /f "tokens=* delims=" %%x in (%%~sa) do echo %%x
I would like all the csv files in a directory which filename does not contain word "summary". Inside the command prompt I can type the following command
dir /b my_dir\*.csv | find /V "summary"
When I try to transfer the above command into a batch file I run into a problem in that the pipe command is not supported in the for loop. That is I cannot do the following
FOR /f %%A in ('dir /b my_dir\*.csv | find /V "summary"') do (
rem want to do something here
)
Can somebody shed some light to me on how to solve the problem above?
Thanks in advance!
You need to escape the | character to prevent its being interpreted at the time of parsing the loop command. Use ^ to escape it:
FOR /f "delims=" %%A in ('dir /b "my_dir\*.csv" ^| find /V "summary"') do (
rem do what you want with %%A here
)
Once escaped, the | becomes part of the '-delimited string. It is only interpreted as a special symbol when that string is parsed separately from the loop, as a "sub-command", according to the syntax. And that is done after parsing the loop.
If you get the problem that Gilbeg got "find: /V': No such file or directory" then it's most likely you have cygwin, or similar, in your path and the batch file's not using the Windows find command. If you modify your script to use the absolute path of the Windows find then the error will go away:
FOR /f "delims=" %%A in ('dir /b "my_dir\*.csv" ^| %SYSTEMROOT%\system32\find.exe /V "summary"') do (
rem want to do something here with %%A
)
You can also just embed a double-quoted string inside the single-quotes string, as in:
FOR /f "delims=" %%A in ('"dir /b my_dir\*.csv | find /I /V "summary""') do #(
ECHO Do something with "%%A"
)
have a look at the Windows PowerShell. Not that I have ever used it myself, mind.
I would like to know how to loop through each line in a text file using a Windows batch file and process each line of text in succession.
I needed to process the entire line as a whole. Here is what I found to work.
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
The tokens keyword with an asterisk (*) will pull all text for the entire line. If you don't put in the asterisk it will only pull the first word on the line. I assume it has to do with spaces.
For Command on TechNet
If there are spaces in your file path, you need to use usebackq. For example.
for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
From the Windows command line reference:
To parse a file, ignoring commented lines, type:
for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do #echo %i %j %k
This command parses each line in Myfile.txt, ignoring lines that begin with a semicolon and passing the second and third token from each line to the FOR body (tokens are delimited by commas or spaces). The body of the FOR statement references %i to get the second token, %j to get the third token, and %k to get all of the remaining tokens.
If the file names that you supply contain spaces, use quotation marks around the text (for example, "File Name"). To use quotation marks, you must use usebackq. Otherwise, the quotation marks are interpreted as defining a literal string to parse.
By the way, you can find the command-line help file on most Windows systems at:
"C:\WINDOWS\Help\ntcmds.chm"
In a Batch File you MUST use %% instead of % : (Type help for)
for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF
What this does:
The "do call :process %%i %%j %%k" at the end of the for command passes the information acquired in the for command from myfile.txt to the "process" 'subroutine'.
When you're using the for command in a batch program, you need to use double % signs for the variables.
The following lines pass those variables from the for command to the process 'sub routine' and allow you to process this information.
set VAR1=%1
set VAR2=%2
set VAR3=%3
I have some pretty advanced uses of this exact setup that I would be willing to share if further examples are needed. Add in your EOL or Delims as needed of course.
Improving the first "FOR /F.." answer:
What I had to do was to call execute every script listed in MyList.txt, so it worked for me:
for /F "tokens=*" %A in (MyList.txt) do CALL %A ARG1
--OR, if you wish to do it over the multiple line:
for /F "tokens=*" %A in (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)
Edit: The example given above is for executing FOR loop from command-prompt; from a batch-script, an extra % needs to be added, as shown below:
---START of MyScript.bat---
#echo off
for /F "tokens=*" %%A in ( MyList.TXT) do (
ECHO Processing %%A....
CALL %%A ARG1
)
#echo on
;---END of MyScript.bat---
#MrKraus's answer is instructive. Further, let me add that if you want to load a file located in the same directory as the batch file, prefix the file name with %~dp0. Here is an example:
cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
NB:: If your file name or directory (e.g. myfile.txt in the above example) has a space (e.g. 'my file.txt' or 'c:\Program Files'), use:
for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
, with the type keyword calling the type program, which displays the contents of a text file. If you don't want to suffer the overhead of calling the type command you should change the directory to the text file's directory. Note that type is still required for file names with spaces.
I hope this helps someone!
The accepted answer is good, but has two limitations.
It drops empty lines and lines beginning with ;
To read lines of any content, you need the delayed expansion toggling technic.
#echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
set "var=%%a"
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
ENDLOCAL
)
Findstr is used to prefix each line with the line number and a colon, so empty lines aren't empty anymore.
DelayedExpansion needs to be disabled, when accessing the %%a parameter, else exclamation marks ! and carets ^ will be lost, as they have special meanings in that mode.
But to remove the line number from the line, the delayed expansion needs to be enabled.
set "var=!var:*:=!" removes all up to the first colon (using delims=: would remove also all colons at the beginning of a line, not only the one from findstr).
The endlocal disables the delayed expansion again for the next line.
The only limitation is now the line length limit of ~8191, but there seems no way to overcome this.
Or, you may exclude the options in quotes:
FOR /F %%i IN (myfile.txt) DO ECHO %%i
Here's a bat file I wrote to execute all SQL scripts in a folder:
REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************
dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
If you have an NT-family Windows (one with cmd.exe as the shell), try the FOR /F command.
The accepted anwser using cmd.exe and
for /F "tokens=*" %F in (file.txt) do whatever "%F" ...
works only for "normal" files. It fails miserably with huge files.
For big files, you may need to use Powershell and something like this:
[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }
or if you have enough memory:
foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" }
This worked for me with a 250 MB file containing over 2 million lines, where the for /F ... command got stuck after a few thousand lines.
For the differences between foreach and ForEach-Object, see Getting to Know ForEach and ForEach-Object.
(credits: Read file line by line in PowerShell )
Modded examples here to list our Rails apps on Heroku - thanks!
cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show rails --app %%i
Full code here.
To print all lines in text file from command line (with delayedExpansion):
set input="path/to/file.txt"
for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
set a=%i
set a=!a:*]=]!
echo:!a:~1!)
Works with leading whitespace, blank lines, whitespace lines.
Tested on Win 10 CMD