I have a very simple batch script that reads a txt file and echo's it's content. The script is:
#echo off
set WORK_BASE_DIR=%~dp0
set BUILD_TXT=%WORK_BASE_DIR%Build.txt
echo %BUILD_TXT%
set PRODUCT_BUILD=0.0
for /F %%i in ("%BUILD_TXT%") do set PRODUCT_BUILD=%%i
echo %PRODUCT_BUILD%
The output of this script is:
D:\Test Dir\Project1\Build.txt \\Correct
D:\Test \\Incorrect
As you can see, the PRODUCT_BUILD is set to the path of the file and not the content of the file. The build.txt file is in the same directory and it contains just one line: 1.0.0000
If I remove the "" from the for statement, it says build.txt file not found, which is expected as the file path contains spaces.
Is there anything that I am missing?
According to the help of for /F (type for /? into a command prompt window), quotation marks denote a literal string, unless you specify the usebackq option:
for /F "usebackq" %%i in ("%BUILD_TXT%") do set "PRODUCT_BUILD=%%i"
In addition, let me recommend to use the quoted set syntax as shown above, which avoids problems with special characters and prevents invisible unintended trailing spaces to become part of the assigned value. Note that this only works if command extensions are enabled, but this is the default in every modern Windows version (based on Windows NT) anyway.
Related
I have the following batch file to make git diff invoke spreadsheet compare UI in windows. So I'm trying to pass the git diff's 2nd (old file) and 5th (new file) arguments to spreadsheet compare in order to make it compare the file using git diff.
So now, this batch file only successfully handles files with NO spaces in the file names, it CANNOT handle files with spaces in the file names.
What code should I add to this script to make this batch code handles file with spaces:
#ECHO OFF
set path2=%5
set path2=%path2:/=\%
ECHO %2 > tmp.txt
dir %path2% /B /S >> tmp.txt
C:/"Program Files"/"Microsoft Office"/root/vfs/ProgramFilesX86/"Microsoft Office"/Office16/DCF/SPREADSHEETCOMPARE.EXE tmp.txt
It currently throw errors like this:
Unhandled Exception: System.ArgumentException: Illegal characters in path.
at System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional)
at System.IO.Path.GetFileName(String path)
at ProdianceExcelCompare.Form1.StatusReady()
at ProdianceExcelCompare.Form1.Init()
at ProdianceExcelCompare.Form1..ctor(String instructionFile)
at ProdianceExcelCompare.Program.Main(String[] args)
fatal: external diff died, stopping at London comparison.xlsx
See the following answers on Stack Overflow:
How to set environment variables with spaces?
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
They explain the recommended syntax set "VariableName=variable value" to define an environment variable and the reasons recommending this syntax.
Why does ECHO command print some extra trailing space into the file?
It explains why the space character left to redirection operator > on an ECHO command line is also written into the file as trailing space and how to avoid this safely on variable text written into the file.
See also Microsoft documentation about Using command redirection operators.
On other command lines than ECHO a space left to > is usually no problem.
It is in general wrong to use multiple times " within an argument string like a file or folder path. There should be just one " at beginning and one " at end. This is explained by help of Windows command processor output on last help page on running in a command prompt window cmd /?.
The Microsoft documentation about Naming Files, Paths, and Namespaces explains that the directory separator on Windows is \ and not / and therefore / should not be used in batch files on Windows in file/folder paths.
The help output on running in a command prompt window call /? explains how the arguments of a batch file can be referenced with which modifiers.
The code rewritten according to information posted above and on the referenced pages:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "path2=%~5"
set "path2=%path2:/=\%"
>"tmp.txt" echo %2
dir "%path2%" /B /S >>"tmp.txt" 2>nul
"%ProgramFiles%\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\DCF\SPREADSHEETCOMPARE.EXE" "tmp.txt"
endlocal
The first line in tmp.txt contains the second argument as passed to the batch file, i.e. without or with surrounding double quotes.
The following code is necessary to write the second argument safely always without " into file tmp.txt even on second argument passed to the batch file is "Hello & welcome!":
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "path2=%~5"
set "path2=%path2:/=\%"
set "Argument2=%~2"
setlocal EnableDelayedExpansion
echo !Argument2!>"tmp.txt"
endlocal
dir "%path2%" /B /S >>"tmp.txt" 2>nul
"%ProgramFiles%\Microsoft Office\root\vfs\ProgramFilesX86\Microsoft Office\Office16\DCF\SPREADSHEETCOMPARE.EXE" "tmp.txt"
endlocal
>tmp.txt echo %~2 cannot be used as not working for something like "Hello & welcome!". Windows command processor would interpret the first string separated by normal space, horizontal tab, comma, equal sign, or no-break space (in OEM code pages) delimited string after & as command or application to execute as described by single line with multiple commands using Windows batch file.
"tmp.txt" could be written everywhere in both batch files also with just tmp.txt. But it is never wrong to enclose the complete file/folder argument string in double quotes even on not being really necessary because of the string does not contain a space or one of these characters &()[]{}^=;!'+,`~. So it is good practice to always enclose a complete file/folder argument string in double quotes. For example running a replace on both batch files searching for tmp.txt and using as replace string %TEMP%\%~n0.tmp would result in using instead of tmp.txt in current directory a temporary file with name of batch file as file name and file extension .tmp in directory for temporary files independent on what is the name of the batch file and what is the path of the directory for temporary files.
The last suggestion is reading this answer for details about the commands SETLOCAL and ENDLOCAL.
The temporary file should be also deleted finally before reaching an exit point for batch file execution.
You can use quotes as below:
It treats the string in quotes as a title of the new command window. So, you may do the following:
start "" "yourpath"
Found it in the below link :
https://ccm.net/forum/affich-16973-open-a-file-with-spaces-from-batch-file
I'm trying to understand a pretty complex (to me it is anyhow) batch file that somebody else has written.
The person who wrote it is no longer around so it's down to me to try and figure out what the hell is going on.
To start with, I need to understand what this line is doing: -
for /f "skip=4 tokens=1,5" %%A in ('dir /tc /o-d %i%\PICKS*') do (
Can anybody help?
1. How to get help on Windows commands?
Help on any Windows standard command can be get by running the command with parameter /? from within a command prompt window.
Try it out with executing in a command prompt window dir /? and for /?.
Or run this long command line with multiple commands:
dir /? >"%UserProfile%\Desktop\Help_on_DIR_FOR.txt" & for /? >>"%UserProfile%\Desktop\Help_on_DIR_FOR.txt" & %SystemRoot%\Notepad.exe "%UserProfile%\Desktop\Help_on_DIR_FOR.txt"
This is like running the three command lines:
dir /? >"%UserProfile%\Desktop\Help_on_DIR_FOR.txt"
for /? >>"%UserProfile%\Desktop\Help_on_DIR_FOR.txt"
%SystemRoot%\Notepad.exe "%UserProfile%\Desktop\Help_on_DIR_FOR.txt"
It runs command DIR to output its help with redirecting the help into file Help_on_DIR_FOR.txt on the desktop. Next it runs command FOR to output its help with appending it to file Help_on_DIR_FOR.txt. And last Windows Notepad is started to display the file Help_on_DIR_FOR.txt.
See the Microsoft documentation about Using command redirection operators for the details on the redirection operators > and >>.
See the Wikipedia article about Windows Environment Variables for the details on the predefined environment variables UserProfile and SystemRoot.
Other sources for help on Windows commands are:
Microsoft's command-line reference
SS64.com - A-Z index of the Windows CMD command line
2. What to know about text encoding of batch files?
The text in a batch file is encoded using one byte per character. That means on using Windows Notepad to create/edit a batch file it is necessary to make sure to save the batch file using ANSI encoding.
Text files using a text encoding with only one byte per character are limited to 256 characters. So there must be a table to define which byte value represents which character. There are many such tables as the mankind on this planet uses more than 256 characters. For text encoding the used code page defines the table used for character encoding.
In a Windows command prompt window (console) is used by default an OEM (Original Equipment Manufacturer) code page while in Windows GUI applications like Windows Notepad is used by default a Windows (ANSI) code page.
Which code page is used depends on Windows region setting as defined for the used account. For example in North American countries code page 437 is used for console and Windows-1252 by Windows GUI applications while in Western European countries code page 850 is used for console and also Windows-1252 by Windows GUI applications.
Run in a command prompt window the command chcp to get displayed which code page is used on console according to region (country) set for your account.
The knowledge about code pages is important on writing a batch file using a Windows GUI editor which contains text with characters with a code value greater 127 decimal because for the upper half of the 256 characters the used code page defines which value represents which character.
It can be easily seen that all non ASCII characters of the help are displayed wrong in Notepad in case of not using English Windows and looking on help output for DIR and FOR to console redirected into a text file viewed with Windows Notepad because of the text file was not created using the Windows (ANSI) code page as expected by Notepad.
3. What does the command line ask for?
Let us analyze the command line
for /f "skip=4 tokens=1,5" %%A in ('dir /tc /o-d %i%\PICKS*') do (
by executing following commented batch file:
#echo off
rem Setup a local environment for the commands below.
setlocal EnableExtensions DisableDelayedExpansion
rem Define the directory to process.
set "i=%TEMP%\UnderstandingDirFor"
rem Create this directory temporarily.
md "%i%" 2>nul
rem Create a file with PICKS at beginning of file name in the directory.
echo PICKS_SampleFile.tmp>"%i%\PICKS Sample File.tmp"
rem Copy the batch file into directory with PICKS in file name.
copy "%~0" "%i%\PICKS_ExampleFile.bat" >nul
rem Copy another file into directory with PICKS in file name.
copy "%SystemRoot%\System32\cmd.exe" "%i%\PICKS cmd.exe" >nul
rem Copy a file into directory with a file name not starting with PICKS.
copy "%SystemRoot%\System32\sort.exe" "%i%" >nul
cls
echo First output is from:
echo/
echo dir "%%i%%\PICKS*"
echo/
dir "%i%\PICKS*"
echo/
pause
echo/
echo ===============================================================================
echo/
echo Second output is from:
echo/
echo dir /tc /o-d "%%i%%\PICKS*"
echo/
dir /tc /o-d "%i%\PICKS*"
echo/
pause
echo/
echo ===============================================================================
echo/
echo Third output is from:
echo/
echo for /f "skip=4 tokens=1,5" %%%%I in ('dir /tc /o-d "%%i%%\PICKS*"')
echo/
for /f "skip=4 tokens=1,5" %%I in ('dir /tc /o-d "%i%\PICKS*"') do (
echo Token 1 = loop variable I = %%I
echo Token 5 = loop variable J = %%J
)
echo/
pause
echo/
echo ===============================================================================
echo/
echo Fourth output is from:
echo/
echo for /F "skip=5 tokens=1,4*" %%%%I in ('dir /A-D /O-D /TC "%%i%%\PICKS *" 2^^^>nul')
echo/
for /F "skip=5 tokens=1,4*" %%I in ('dir /A-D /O-D /TC "%i%\PICKS *" 2^>nul') do (
if /I "%%J" == "PICKS" (
echo Token 1 = loop variable I = %%I
echo Token 5 = loop variable K = %%K
)
)
echo/
pause
rem Delete the created directory with the four files.
rd /S /Q "%i%"
rem Purge the local environment and restore initial environment.
endlocal
Note: The batch file uses "%i%\PICKS*" instead of %i%\PICKS* to work also for directory paths containing a space character or one of these characters &()[]{}^=;!'+,`~. The path of the directory for temporary directories and files referenced with %TEMP% included in %i% could contain a space character which requires the usage of double quotes.
The first output into console window is from:
dir "%i%\PICKS*"
It can be seen on output that the files (or directories) matching the wildcard pattern PICKS* are listed with last modification date at beginning and in order as used internally by the file system.
The file sort.exe is not output because it's file name does not start with PICKS.
What DIR outputs exactly depends on language of Windows. But the first five lines are the header and the last three lines are the summary in language of Windows.
The second output into console window is from:
dir /tc /o-d "%i%\PICKS*"
The output of the list is now in reverse order by date/time because of option /o-d using creation date because of the option /tc.
By default the file/directory with the oldest date is output first and the file/directory with the newest date is output last on using /od. The order is reverse with /o-d which means output is first the newest and last the oldest file/directory.
It can be seen on comparing the two outputs that the creation date of all copied files is newer than their last modification date.
The reason is that the creation date is the date a file/directory was created in current directory and NOT when the file itself was created the first time anywhere.
For that reason the creation date is most often not really useful and using the creation date might be also not useful here. But this can't be determined without knowing what the entire batch file is written for.
The third output into console window is from:
for /f "skip=4 tokens=1,5" %%I in ('dir /tc /o-d "%i%\PICKS*"') do (
echo Token 1 = loop variable I = %%I
echo Token 5 = loop variable J = %%J
)
FOR starts a new command process in background using cmd.exe with option /C for an automatic close for executing the specified command line dir /tc /o-d "%i%\PICKS*". To be more precise there is executed by FOR:
%ComSpec% /c dir /tc /o-d "C:\Users\UserName\AppData\Local\Temp\PICKS*"
ComSpec is a predefined environment variable with full qualified file name of Windows command processor which is usually C:\Windows\System32\cmd.exe.
The output of the entire command process to handle STDOUT is captured by FOR and processed line by line after background command process finished and closed itself.
for /F ignores by default all empty lines. The other lines are by default first split up into substrings using normal space and horizontal tab as string delimiters which means no substring contains any space/tab. If the first space/tab delimited substring starts now with a semicolon being the default end of line character, the line is not further processed by FOR and so also ignored like an empty line. Then the first substring is assigned to specified loop variable and the single command or the command block is executed next.
Command FOR is instructed with option skip=4 to skip the first four lines of captured output and start processing the output with line five which is the last empty line of header of DIR output.
Command FOR is instructed with option tokens=1,5 to not assign only first space/tab delimited string to specified loop variable I, but also the fifth space/tab delimited string to the loop variable being the next one after I in ASCII table if there is a fifth substring (= token) at all which is loop variable J.
This substrings/tokens to loop variable assignments feature is the reason why loop variables are case-sensitive while environment variables are not case-sensitive.
Command FOR ignores a line if the first specified token as specified with tokens= cannot be determined from a line. But it does not ignore lines on which not all strings of interest can be found in line as it can be seen on third output.
What fifth space/tab delimited string assigned to loop variable J should be in original batch code depends on what the directory referenced with %i% contains - files or directories - and how the file/directory names starting case-insensitive with PICKS really look like.
For the example I assumed PICKS* matches files with file name starting with PICKS (note the space at end) and more characters not containing a space character.
By looking on third output it can be seen that the names of the three PICKS* are not assigned all to loop variable J as expected and the summary lines are also processed.
I suppose this does not happen in original batch file because of file/directory names do not contain another space character after PICKS and the FOR loop is exited with command GOTO after processing first file/directory name.
The fourth output into console window is from:
for /F "skip=5 tokens=1,4*" %%I in ('dir /A-D /O-D /TC "%i%\PICKS *" 2^>nul') do (
if /I "%%J" == "PICKS" (
echo Token 1 = loop variable I = %%I
echo Token 5 = loop variable K = %%K
)
)
This is an improved version suitable to output only the creation date and the name of the files in temporary directory matching the wildcard pattern.
The DIR option /A-D is added to ignore subdirectories and get just a list of files of which file name is matched by the wildcard pattern.
The wildcard pattern is modified to PICKS * which results in command DIR not outputting anymore a line for file PICKS_ExampleFile.bat because of the underscore instead of the space in the file name.
On DIR command line 2^>nul is appended for suppressing a perhaps output error message. Command DIR outputs an error message to handle STDERR not processed by FOR and therefore written to console when it can't find a file matching the wildcard pattern in the specified directory or when the directory does not exist at all. This error message is redirected to device NUL to suppress it. The redirection operator > must be escaped here with caret character ^ to be interpreted first as literal character on parsing FOR command line by Windows command interpreter, but as redirection operator on execution of DIR command line in background command process.
The skip option of command FOR is modified to skip=5 to skip the first 5 lines, i.e. the entire header block of command DIR.
The tokens option of command FOR is modified to tokens=1,4*. This results on lines containing a file name matching the wildcard pattern PICKS * in assigning creation date of file to loop variable I, PICKS to loop variable J and everything after the space(s) after PICKS in line without further splitting up on spaces/tabs to loop variable K.
The IF condition compares case-insensitive, because of /I, the string assigned to loop variable J with PICKS and outputs creation date and file name only if the compared strings are equal. This IF condition filters out the summary lines on output.
Because of * in tokens=1,4* the entire file name with the exception of PICKS is output even if the file name contains more space characters like in Sample File.tmp.
4. How to debug a batch file?
Windows command processor outputs by default each command line respectively command block defined with ( ... ) after processing it before execution. The output of the command lines/blocks before execution can be disabled with using #echo off at top of the batch file whereby # prevents already the output of this command line.
But on debugging a batch file it is often necessary to see what is really executed. This can be achieved with either removing #echo off, or changing it to #echo ON or comment this command line out with #rem #echo off or with ::#echo off whereby the last solution changes the command line into an invalid label line.
It is of course also possible to keep #echo off at top of the batch file and use inside the batch file echo on and some lines below #echo off to get displayed on execution just the commands between those two command lines to debug just a specific block of the batch file.
And for debugging the batch file it should not be executed by just double clicking on it in Windows Explorer. This results in starting cmd.exe implicit with option /C for executing the batch file and close the command process and therefore also the console window immediately on exiting the batch file execution.
The closing of the console window is not good for debugging a batch file because the executed commands can't be seen and also the error message output by Windows command processor on detecting a syntax error resulting in an immediate exit of batch file processing is not readable with console window automatically closed.
For that reason debugging a batch file should be done by opening a command prompt window which results in implicit execution of cmd.exe with option /K to keep command process running and its console window open after execution of the batch file which is entered with its file name and if needed with full path in the command prompt window for execution.
Another advantage of running the batch file from within a command prompt window is the possibility to use UP and DOWN keys to re-select a once entered command line or string entered on a user prompt within batch file with set /P from input buffer of command process.
That's a for-loop with the /f option. It loops through a file or command, in this case the command dir /tc /o-d %i%\PICKS*.
Take a look at what dir /tc /o-d word* on its own does (read up on options wtih dir /?), it'll make understanding the loop easier.
Basically, the output of the command is dir (show files in directory) with the timefield showing the creation date and all files sorted by date in descending order. The command applies to the folder %i% (a variable set beforehand). "PICKS*" is the 'mask', i.e. all files starting with "PICKS" are shown. That's what the wildcard (asterisk) means (any characters can follow).
The for-loop now takes that output and assigns it to %%A (temporary iteration variable). It skips the first 4 lines (in the case of dir just header that you don't want to have), and for each following line (the files) picks out the first and the fifth word (delimited by spaces, as space is the default delimiter). %%A is now the date, %%B (the second specified token/fifth word) the second word of the filename (if there is any). Those variables can be used in the do (... part.
I am trying to create a list of files (about 4000) with batch file but without the extensions, some of the file names have - or _ or spaces which I would like to keep them the same, and then I am going to copy and paste the list inside Excel and run a macro that I found on this website to create individual files with different extension using the names on that list. I hope I make sense.
Here is my attempt so far:
for /f %%a in ('dir /b *.dsg') do #echo %%~na >txt1.txt
But this one just creates a list with only one name.
The batch code for this simple task is:
#echo off
del txt1.txt 2>nul
for /F "delims=" %%I in ('dir *.dsg /A-D /B 2^>nul') do echo %%~nI>>txt1.txt
The command DEL is used to delete a probably already existing file txt1.txt with redirecting the error message output to handle STDERR to device NUL to suppress it in case of the file does not exist in current directory.
Next the command DIR is executed by FOR in a separate command process. DIR lists only the names of all files matching the pattern *.dsg because of /A-D (not directory attribute) in bare format because of /B.
The error message output by DIR in case of no *.dsg file in current directory is suppressed by redirecting it to device NUL. The redirection operator > must be escaped here with caret character ^ to be interpreted as literal character when Windows command interpreter parses the FOR command line. Later on execution of DIR command line > is interpreted as redirection operator.
The list output by DIR is parsed by FOR line by line. The option delims= disables splitting up each line using spaces/tabs as delimiter. So assigned to loop variable I is always the entire line read from output of DIR.
Output by ECHO to handle STDOUT is the string left of last dot, i.e. the file name without file extension. This output is redirected to a file with appending the line to already existing file contents.
A space between %%~nI and redirection operator >> would be also output by ECHO and therefore also written as trailing space into the file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
for /?
Read also the Microsoft article about Using Command Redirection Operators.
#user8033911, based upon your latest comment, there seems no reason why you cannot replace the file extension with another as part of the same process.
The code below entered directly in the Command prompt window should show you, it replaces, .dsg with .new.
For /F "EOL=/Delims=/" %A In ('Where/F .:*.dsg') Do #Echo %A to "%~dpnA.new"
If you still cannot understand just comment below explaining where you are having difficulty.
The batch command below will get me the newest file in a folder, however I'm only looking for files with a specific extension. Can anyone explain how to specify the extension (i.e. .jpg)
FOR /F "delims=|" %%I IN ('DIR "C:\Jenkins\Releases\C9metro" /B /O:D') DO SET NewestFile=%%I
I suggest to use the following lines:
FOR /F "eol=| delims=" %%I IN ('DIR "C:\Jenkins\Releases\C9metro\*.jpg" /A-D /B /O-D /TW 2^>nul') DO (
SET "NewestFile=%%I"
GOTO FoundFile
)
ECHO No *.jpg file found!
GOTO :EOF
:FoundFile
ECHO Newest *.jpg file is: "%NewestFile%"
The FOR loop can be also optimized to a single command line:
FOR /F "eol=| delims=" %%I IN ('DIR "C:\Jenkins\Releases\C9metro\*.jpg" /A-D /B /O-D /TW 2^>nul') DO SET "NewestFile=%%I" & GOTO FoundFile
ECHO No *.jpg file found!
GOTO :EOF
:FoundFile
ECHO Newest *.jpg file is: "%NewestFile%"
FOR starts in background one more cmd.exe with option /c and the command line within ' appended as additional arguments. There is executed in this case in background with Windows installed into C:\Windows:
C:\Windows\System32\cmd.exe /c DIR "C:\Jenkins\Releases\C9metro\*.jpg" /A-D /B /O-D /TW 2>nul
The internal command DIR searches now for file system entries in the specified directory matching the wildcard pattern *.jpg with following additional restrictions.
The parameter /A-D makes sure ignoring subdirectories which unusually end by chance also with the string .jpg.
The parameter /B turns on bare output format. In this case are output just the file names without path by command DIR never enclosed in " even on containing a space or one of these characters &()[]{}^=;!'+,`~ which require the file name string to be enclosed in " on further processing it by cmd.exe on other command lines.
The parameter /O-D results in getting output by DIR the found file names listed by date in reverse order from newest to oldest. In other words the file name of the newest file is output first and the file name of the oldest file is output last.
And parameter /TW makes sure the last modification time (write access) is used for ordering the found file names of the JPEG files in date order and not the creation or the last access time.
There could be no file name matching the wildcard pattern *.jpg in long or short 8.3 name in which case DIR outputs an error message to standard error stream STDERR of the background command process. cmd.exe processing the batch file would redirect that error output to its own standard error stream. That would result in displaying the error message in the console window not really useful for a user of the batch file. The usage of 2>nul instructs cmd.exe started in background to redirect the error message to device NUL to suppress it.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
FOR respectively cmd.exe processing the batch file captures all output written to standard output stream of in background started cmd.exe and processes it line by line after started cmd.exe closed itself after finishing executing the command DIR.
FOR on using option /F ignores always empty lines which is no problem here as DIR with the used options does not output empty lines.
FOR would next split up the lines into substrings using horizontal tab and normal space as string delimiters, would look next if first tab/space separated string begins with a semicolon in which case it would also ignore the entire line for further processing, and would otherwise assign just the first tab/space separated string to the specified loop variable I before running the commands in body of FOR.
The default line splitting behavior is not wanted as JPEG file names can contain one or more spaces. The usage of the option delims= defines an empty list of delimiters which turns off the line splitting behavior.
It is very unusual but nevertheless possible that a JPEG file name begins with ; (semicolon). Such a file name should not be ignored by FOR. The option eol=| defines a vertical bar as end of line character which no file name can contain ever. Microsoft lists the characters not allowed in a file name on Windows file systems in the documentation about Naming Files, Paths, and Namespaces.
So, the first file name output by DIR being from the newest file is assigned completely to the loop variable I and executed is the command SET to assign this string to the environment variable NewestFile.
The loop is exited on first found file matching the wildcard pattern *.jpg is assigned to the environment variable. That makes this method faster than letting DIR output the file names from oldest to first and assigning all file names one after the other to the variable NewestFile up to last found file which would be the newest file.
There is an error message output on DIR could not find any file and so FOR could not assign any file name string to the loop variable I and run once the commands SET and GOTO. Then the batch file processing is exited in this case as described in detail by Where does GOTO :EOF return to?
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
dir /?
echo /?
endlocal /?
for /?
goto /?
set /?
setlocal /?
See also:
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
Single line with multiple commands using Windows batch file explaining the unconditional command operator & as used in the second example.
It's early... figured this one out:
'DIR "C:\Jenkins\Releases\C9metro\*.jpg"
I want to copy some files to same destination.
Files which will be copied are listed in a text file.
So, how to read file list from text file and copy via using cmd
command?
I tried this command:
for /f "delims=" %%L in (foo.txt) do copy "%%L" new_folder
Similar question was asked in this website, I know that. When I use this command, files will be copied; but folders which include these files won't be copied.
I want to copy files with their directories.
What should I do? (Sorry for my awful English.)
You use %%L in a batchfile and %L when typing interactivly.
Your command, depending on other factors, should have a path specified for new_folder.
& seperates commands on a line.
&& executes this command only if previous command's errorlevel is 0.
|| (not used above) executes this command only if previous command's errorlevel is NOT 0
> output to a file
>> append output to a file
< input from a file
| output of one command into the input of another command
^ escapes any of the above, including itself, if needed to be passed to a program
" parameters with spaces must be enclosed in quotes
+ used with copy to concatinate files. E.G. copy file1+file2 newfile
, used with copy to indicate missing parameters. This updates the files modified date. E.G. copy /b file1,,
%variablename% a inbuilt or user set environmental variable
!variablename! a user set environmental variable expanded at execution time, turned with SelLocal EnableDelayedExpansion command
%<number> (%1) the nth command line parameter passed to a batch file. %0 is the batchfile's name.
%* (%*) the entire command line.
%<a letter> or %%<a letter> (%A or %%A) the variable in a for loop. Single % sign at command prompt and double % sign in a batch file.
.
--
Ok ,I have solved my problem via searching another cmd command:
for /f "delims=" %%i in (filelist.txt) do echo F|xcopy "-Source root folder-\%%i" "-Destination folder-\%%i" /i /z /y
In spite of the fact that I have solved my problem myself, thanks guys for your helps.
I appreciate it too much!