ABSTRACT : This article delves upon FOR loops in all its weirdness.
THE LOOP PLAYGROUND
CMD.exe provides FOR loops that work in a rather awkward manner but is quite powerful indeed. In this section let us see how can we understand the for loop switches and their purposes using a problem description and solution approach.
FOR loops remind us of the pleasures of iterations and what can be done by repeating an operation a certain number of times. Adding a condition to the scenario means we can make better use of logical operations.
FOR loops in windows cmd.exe help us to do line based parsing quite effectively. Further the feature that enables us to parse the output in memory of executed commands, including wmic and piping of additional cmd commands makes the process more facilitated. The use of the IF command adds a flavour of programming like decision making that gives a limited albeit flexible enough range of options.
As you will see it in the examples below, there are many ways to do the same and similar things, while the same features can be used to do quite different things. It’s kind of a dualism I guess, I don’t really know.
IF ?? (BE) ELSE (!BE)
Let’s have quick look of the IF command.
Type IF /? in the cmd prompt.
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
The 3 modes are ERRORLEVEL number, string comparison and file existence Boolean check.
The NOT is used to invert the logical condition. It is not enclosed in square brackets if to be used.
The ‘command’ if satisfying the IF condition is executed. However if and ELSE condition is required then the preceding command has to be enclosed in ().
Example from the man page –
IF EXIST filename. (del filename.) ELSE echo filename. Missing
It’s quite self explanatory.
A set of conditional processing definitions are provided as compare-operators.
IF [/I] string1 compare-op string2 command
These compare operators are –
EQU – equal
NEQ – not equal
LSS – less than
LEQ – less than or equal
GTR – greater than
GEQ – greater than or equal
The comparisons have a dual nature. The string is the default comparison type. However, if the strings are both numbers then they are subjected to a numeric comparison.
Open cmd.exe by pressing WINDOWS_KEY+R to get the run dialog, type cmd and press ENTER.
Type – for /? In the prompt to get the page paused list of the for help description (without the use of the more command piping).
The general layout of this command is as follows ;
FOR<switches D /R /F /L> <context based switch options> %variable in (set/file/commands) do <@commands>
The simple version of the above would be –
FOR <look IN-to a dataset > DO <something>.
The dataset is switch sensitive.
/D enumerate the directories(not files) and feeds that as a data set.
/R recursively traverses the directory tree and feeds that tree (folder and files) as a data set.
/F parses the memory / file and extracts each line (CR+LF/No blank lines) and takes further parameters to work with each line(tokens/delimiters/line skips). Each parsed line is fed as a dataset. Memory is used as the buffer for command run and its output within the brackets. Regular commands from cmd and piped commands can be used to generate the dataset which will be in turn parsed line by line from memory and processed as programmed.
/L generates numbers as in a traditional numeric loop and feeds that number list as a dataset.
The main keywords in this line are – ‘FOR’, ‘IN’ and ‘DO’.
All the commands are case insensitive in cmd and thus FOR /F is equivalent to for /f and fOr /F.
We will discuss the context based switch options that are especially required FOR /F option while reading command output from memory or a text file.
A set of attributes can be extracted from folder or files when used in combination with the FOR /F mode. The kind of properties that can be queried off are listed below –
%~I – expands %I removing any surrounding quotes (“)
%~fI – expands %I to a fully qualified path name
%~dI – expands %I to a drive letter only
%~pI – expands %I to a path only
%~nI – expands %I to a file name only
%~xI – expands %I to a file extension only
%~sI – expanded path contains short names only
%~aI – expands %I to file attributes of file
%~tI – expands %I to date/time of file
%~zI – expands %I to size of file
%~$PATH:I – searches the directories listed in the PATH
And they can also be compounded to give –
%~dpI – expands %I to a drive letter and path only
%~nxI – expands %I to a file name and extension only
%~fsI – expands %I to a full path name with short names only
%~dp$PATH:I – searches the directories listed in the PATH
environment variable for %I and expands to the
drive letter and path of the first one found.
%~ftzaI – expands %I to a DIR like output line
TIP : As you will have to construct statements it’s good to think of their execution path as linear, regardless of the kernel mode context switching and scheduling mechanism that give us the illusion of simultaneous execution. Inner most commands are run the first and the execution path starts from the left side of the statement and travels to the right side.
LEARN LOOPS IN 24 STATEMENTS
PROBLEM 1: List the sizes and names of all subfolder in the target directory (one for C:\TEST and the current directory).
ANS :: CASE 1- for /D %i in (C:\TEST\*.*) do @echo %~zi %i
CASE 2-for /D %i in (*.*) do @echo %~zi %i
PROBLEM 2: Iterate from 2 to 20 using a FOR loop and display it in the console.
ANS :: for /L %i in (2,1,20) do @echo %i
PROBLEM 3: You need copy all .m4v extension video files from a repository folder TEST (including subfolders) to a dummy folder BIN in the root directory, use a for loop to do the same.
ANS:: for /R “C:\TEST” %i in (*.m4v) do @xcopy “%i” C:\BIN
FOR /R sets the operating mode to directory recursive mode, which is what we need.
The format for this command would require the source directory to be specified immediately after the switch within double quotes.
All for loop statements require the use of a variable that is alphabetical in sequence. For most examples as in loop counter variables during programming, the convention is to use the letter ‘i’.
If more variables are needed then we continue with the next letters in sequence. If we had started from ‘a’, the next variable would have to be ‘b’ unless in special cases that are implicitly divided into several variables such as the use of tokens later on.
All variables in every FOR statement has to be prefixed with a modulus sign ‘%’.
The next compulsory key word is ‘IN’ in every variation of the FOR command.
The parentheses are mandatory and hold the ‘thing’ to iterate/parse into. Any sort of output to be parsed no matter how complex or long has to be contained in these two brackets for a particular for statement.
In this case we pass the wildcard string containing the familiar * as the wildcard and the string to search in the filenames. What happens here is the directory tree containing the folder names and the full filenames (path+filename+extension) is traversed and every entry attribute is compared to the extension ‘m4v’ all the valid entries are collated into the final list.
All of this is accumulated in the memory, only after the completion of the bracketed commands does the ‘do’ part of the for loop start.
The @ sign prefixing negates the separate output display of the command-run itself in stdout and snubs that into the background giving only the desired command(s) final output.
Finally, the action command itself – xcopy %i C:\BIN. The %i acts as a placeholder for the full path of the files containing the extension m4v and thus facilitating xcopy to do its job (copy from source to destination).
ANS :: for /R “C:\TEST” %i in (*.m4v) do @echo %i; >> SAVE.txt
The statement below saves the list of m4v files in recursive mode to a text file in appending mode while adding a semi-colon on every line. The semicolon acts as a delimiter when reading back from this text file list from the filesystem using the for /f switch. This is one way to do it. The other will be discussed in the length of the article.
PROBLEM 4: Read a text file and delete all the files contained in that text file. One file per line, the file is delimited using ; to denote the end of each line.
ANS :: for /F “delims=;” %i in (SAVE.txt) do @del “%i”
A thing to remember about FOR /F mode is that it does not read blank lines as lines. This is unlike the behaviour of find /c /v “” where in even blank lines and carriage returns are counted as lines. This makes counting very accurate using for loops.
The statement below uses the FOR /F switch to read from file/memory from the file above. In this case the current directory is C:\TEST and hence just passing the filename works. In all for statements hereon if the full path is not given, assume that it is in the current directory. If not present you would get an error.
Notice that the ‘delims’ parameter is passed in ‘’’’ while assigning the value of the delimiter ‘;’. This is in accordance with the list and syntax of the FOR /F mode. Once learned it’s quite simple really.
Finally the activity to be done is to delete all such files (m4v ext) by reading the readymade list.
The reasons for using delimiters is that the FOR /F command on its own does not parse spaces in filesystem paths and thus ‘C:\TEST’ would be parsed just fine, however ‘C:\DIN OF BIN’ would be parsed as C:\DIN essentially and thus feed this non-existent folder to the command thereafter giving an error.
PROBLEM 5: Count the number of files in a target directory. Use a repository file that saves each video path and update the number of files/lines in that repository file. Display the number count only in a static position in the left most corner of the console.
ANS :: for /R “C:\TEST” %i in (*.m4v) do @echo %i >> TMP.txt | cls | type TMP.txt | find /c /v “”
The above statement parses the folder tree and saves the video files to TMP.txt in the current directory, clears the screen intermittently and displays the count of lines in the resulting file in realtime. It is displayed in the top left and does not keep appending . It’s a little blurry but still gives a position static display of realtime data. Better options to do this are quite limited, though there might be more effective work around.
PROBLEM 6: Continously delete all exe files in a malware dump directory. Use a timer between each deletion.
ANS :: for /R “C:\MALWAREDUMPSITE” %i in (*.exe) do @del “%i” & ping -n 1 localhost > nul
This statement keeps deleting executable files in a target folder. Here notice that del is passed the file path strings within “” which effectively processes the blank spaces in file paths in the /R mode. This is different from the use of delimiters in for /F mode. The other method is using tokens, as will see soon.
The ping trick is quite well known now using the ping count command. The time used to do each ping is not quite precise(exact) though accurate (average is stable) enough for our purposes. Here we are pinging localhost and feeding the output to nul (sort of console output recycle bin). Thus we don’t see the pinging text cluttering the actual desired output.
A few other commands like netstat also allow the use of timers, however, once started these other commands actually keep running and thus don’t allow the continuation of the command daisy chain. Ping is the only inbuilt command that actually can be used as a timer workaround.
PROBLEM 7: Find all exe and dll files in a target directory from a target subdirectory tree using FINDSTR regex strings.
ANS :: for /R “C:\TEST” %i in (*.*) do @echo %i | findstr [.][ed][xl][el]
This time we are searching for all/any files recursively in the target folder and parsing the whole output in memory and using findstr regex to filter exe and dll files only. This method is good for mass extraction in minimal lines of code.
PROBLEM 8: Continously list the services running.
ANS :: for /L %i in (1,0,10) do @tasklist /svc
for /L is used where in the 1,0,10 denote the starting counter value, the step and the terminating value. The step being 0, this is an immediate infinite loop. Basically tasklist /svc will be run infinitely. This would be useful for giving a realtime monitoring view, in this case the output can be further gleaned to make it like an alarm when a new service (known name strings) is started, without listing the usual benign ones, by piping FIND or using FC to diff with a text list of known strings and setting a conditional display using the IF command. You could try this yourself.
PROBLEM 8: Using FOR loop and taskkill filters, continuously kill notepad.exe and use a timer within each successive operation.
ANS:: for /L %i in (1,0,1) do @taskkill /fi “imagename eq notepad.exe” & ping -n 3 localhost > null
Here notepad.exe is continuously killed while keeping the display refreshed to visible speeds in an infinite loop. Press CTRL+C to break any such loop.
PROBLEM 9: Read a file from the disk and delimit the contents of each line with a ‘;’. Thereafter display the SIZE and NAME of each file from the playlist. You could use a buffer to accumulate the delimited list of file paths and later delete that after the operation is done.
ANS :: (for /f “tokens=1*” %i in (‘type “C:\OWNZ\MDEIA\MUZ\full.m3u”‘) do @echo %i %j; >> C:\ownz\t.txt) & (for /f “delims=;” %i in (C:\ownz\t.txt) do @echo %~zi %~ni) & (del C:\ownz\t.txt)
The file was full.m3u was stored earlier as ::
for /f “tokens=1*” %i in (‘dir /b /s C:\OWNZ\MDEIA\MUZ\*.mp3’) do @echo %i %j >> C:\ownz\mdeia\muz\full.m3u
Here an m3u file is taken (music playlist-Winamp), wherein the full file paths are listed to a temp file t.txt after delimiting with ‘;’(read the @echo statement properly) and on successful completion of the above a second for loop parses the newly created and delimited t.txt file is parsed and the file attributes are processed from just the file paths and displayed on the console stdout. After the successful completion of the second for loop the file t.txt is deleted
This is a feature provided in for /f loops. The use of %~zi will enumerate the file sizes in bytes for each file read in that variable. %~ni will enumerate the names of the files only sans the path or extension.
Notice the use of a new parameter “tokens=1*”. The use the tokens parameter keyword denotes the indexing of spaced text within each line. It simulates the use of columns, if that can be taken as an analogy. Think of a line containing spaces or tabs as a set of fields. Now each field can be tokenised starting from the number 1 (not 0).
C:\DIN TO BIN
can be tokenised as
The tokens parameter takes this index list as a wildcard as well using the asterisk character.
“tokens=1,2*” for the above instance would mean,
“tokens=1*” would mean
Thus, the index count is always incremental and ends with a star if all the rest of the line regardless of the space or tabbed contents. This brings our 3rd method of reading a line, using the tokens parameter keyword. Remember the ‘remaining part’ or the ‘*’ index includes anything after the 2nd index is filled. But this part has to be accessed using a separate variable and this in keeping with use of alphabet series the next logical letter has to be used in the same fashion as the earlier variables.
An interesting thing is that the title of the cmd displays the contents of %i and %j. This might be another alternative to update the display at a single location.
PROBLEM 10: Display the SIZE NAME and EXTENSION of the subdirectory tree of C:\TEST (folders and files).
ANS :: for /R C:\TEST %i in (*.*) do @echo %~zi %~ni %~xi
This statement displays the size, name and extension of each file in the target directory.
PROBLEM 11 : Read entire lines (even containing spaces) to successfully enable the display of each line read from a file c.txt in the current directory.
ANS :: for /F “tokens=1*” %i in (c.txt) do @echo %i %j
Here we learn about the tokens keyword in its most simple variation to read a complete line from a text file and display it to the stdout.
PROBLEM 12 : Copy all files having extension .rns from C:\OWNZ subdirectory tree to C:\OWNZ.
ANS :: for /f “tokens=1,2*” %i in (‘dir /b /s C:\ownz\*.rns’) do @xcopy “%i %j %k” C:\ownz
Here, we feed the variables %i, %j and logically %k within double quotes to xcopy. The tokens keyword indicates that the first 2 spaces will be tokenised and thereafter the rest of the lines will be appended in the last variable holding the asterisk value.
Notice how cmd.exe commands are passed within single quotes.
VARIATION : Use a single token instead of 2.
for /f “tokens=1*” %i in (‘dir /b /s C:\ownz\*.rns’) do @echo %i %j
The purpose of this tokenising is quite a few.
1) One that comes to mind would be rearranging the output columns to an order other than the default sequence.
2) The other benefit would be the breakdown of the text output per line for more effective parsing.
3) Exact text location extraction
Undoubtedly syntax like ‘wmic process get processid’ is a lot simpler to use, though it would be indeed cumbersome to work on text files and other formats that might require custom parsing logic. Here FOR loops definitely keep the leverage. Infact though data retrieval in wmic is quick and intuitive, the data formatting and parsing/reordering options are rather limited, unless standard issue XML and HTML is exactly what you need and thereafter only 3rd party tools would enable salvaging the data from it.
TIP : Here on the use of tokens to parse a full line regardless of the number of spaces and returns, just use “token=1*”. This is the first space will be the tokenising one and the rest of the line is taken up by the second variable.
PROBLEM 13: Search for all text files in ‘C:\ownz\soft’ and display the file paths. Further, show the count of lines per file in the display.
ANS :: for /f “tokens=1*” %i in (‘dir /b /s C:\ownz\soft\*.txt’) do @echo %i %j & (@echo %i %j >> C:\ownz\tmp.txt | @type C:\ownz\tmp.txt | find /c /v “”)
VARIATION : Delete the tmp file from the operation and show when the entire process has complete by displaying the string – “TMP DELETED”
ANS :: (for /f “tokens=1*” %i in (‘dir /b /s C:\ownz\soft\*.txt’) do @echo %i %j & (@echo %i %j >> C:\ownz\tmp.txt | @type C:\ownz\tmp.txt | find /c /v “”)) & (@del C:\ownz\tmp.txt & @echo File TMP Deleted)
Variation : Update each text file with a line count.
ANS:: (for /f “tokens=1*” %i in (‘dir /b /s C:\OWNZ\TEST\*.txt’) do @echo %i %j & (@type “%i %j” | find /c /v “” & @type “%i %j”| find /c /v “” >> “%i %j” ) & explorer %i %j)
The above statement parses the lines from all text file in the directory specified and counts the number of lines in each file and appends the count to the end of each file and deletes the temporary file after the operation. You could open any file and see the count recorded at the bottom of the file.
PROBLEM 14: Seach for all exe and dll files in ‘C:\ownz\soft’ and save them to a file ‘exelist.txt’ in the current directoy for later retrieval. Count the number of lines in the resulting file and display it and at the same time append that number to the end of the exelist.txt file. After that start notepad with exelist.txt loaded in it. Use a single line statement to do all the above.
ANS :: (for /f “tokens=1*” %i in (‘”dir /b /s C:\ownz\soft\*.exe & dir /b /s C:\ownz
\soft\*.dll”‘) do @echo %i %j >> C:\ownz\exelist.txt) & (@type C:\ownz\exelist.txt | find /c /v “”) & (@type C:\ownz\exelist.txt | find /c /v “” >> C:\ownz\exelist.txt) & (notepad C:\ownz\exelist.txt)
Here, all exe and dll extension executable files are accumulated in memory using linear approach of command execution. First, “dir /b /s C:\ownz\soft\*.exe” runs. Now the memory contains a per line list of the exe files.
Next “dir /b /s C:\ownz\soft\*.dll” runs. Now, the memory contains the original list of exe files with the dll file list appended directly after that. This memory list is dumped to the file system for later recovery using echo with 2 variables to a file exelist.txt. Note the use of Parentheses. Each FOR loop will complete linearly from left to right. Further this sequence will only continue if the last one was successful. ‘&’ provides the fail safe conditioning logic so that errors are not propagated to the next one in the chain.
There after display the count to the screen (stdout) and append the total count of executable files to the end of the exelist.txt file.
After all the preceding operations are done open notepad with exelist.txt opened in it saveing the manual labour of starting notepad to check for the operation.
PROBLEM 15: Search for all exe files recursively from a ‘C:\ownz\soft’ and display the filesize and the full path of each file.
ANS :: for /f “tokens=1*” %i in (‘”dir /b /s C:\ownz\soft\*.exe”‘) do @echo %~zi %i %j
Here we get the filesize, and the file path in a simple 2 column display from the dir /b command output. Here first dir runs its course and thereafter we extract the path names and the sizes of each file and change the output format to our requirement.
PROBLEM 16: Search through a directory for all text files and display the full path only if the filename equals to ‘exelist’ (don’t check for extension).
ANS:: for /f “tokens=1*” %i in (‘dir /b /s C:\ownz\*.txt’) do @if %~ni==exelist (echo %i)
This displays the of exelist from the memory list of text files searched recursively. You are demonstrated the use of the ‘if’ command in cmd.exe. Here if name equals exelist the echo the file path. Sure look like a thorough way to search for a file location.
PROBLEM 17: Search for all EXE files recursively in a target directory and display the file path only if the size of the file is greater than or equal to 600,000 bytes.
ANS :: for /f “tokens=1*” %i in (‘dir /b /s C:\ownz\*.exe’) do @if %~zi GEQ 600000 (echo %i)
Here we check for file size greater than or equal to ~600KB and only then display the full file paths to the console. Notice how the IF statement takes the IF conditional action in parentheses. The else keyword would follow likewise.
PROBLEM 18: Parse two separate text files and display their contents. Use tokens parameter to include full lines containing spaces with minimal tokenising and not delimiters.
ANS :: for /f “tokens=1*” %i in (C:\ownz\n.txt,C:\ownz\n2.txt) do @echo %i
PROBLEM 19: Parse a list of mp3 files in an m3u playlist file and find mp3’s whose sizes are >= 10000 bytes. Display them in a 2 column format – SIZE NAME. Name would be sans file path and extension.
ANS :: (for /f “tokens=1*” %i in (‘type “C:\OWNZ\MDEIA\MUZ \full.m3u”’) do @echo %i %j; >> C:\ownz\t.txt) & (for /f “delims=;” %i in (C:\ownz\t.txt) do @if %~zi GEQ 10000 (echo %~zi %~ni)) & (del C:\ownz\t.txt)
In this statement we are searching for all mp3 files in the m3u playlist that have sizes greater than equal to 10KB and display the size column first and the names of each file only (without path and extension.) We use delimeters and a temporary buffer file, which is deleted after.
PROBLEM 20: Reorder output of tasklist command and skip the first 4 lines. The divider line, the headers line, System Idle process and System. Reverse order the column display.
ANS :: for /f “tokens=1,2,3* skip=5” %i in (‘tasklist’) do @echo %l %j %k %i
Here we learn about the skip parameter keyword for the FOR /F loop mode. Skip essentially skips the first n number of lines from the to be processed data set (file/memory). The index starts from 1. Essentially the display runs from the next line after the skipped lines. Therefore you just feed the line number you want to start from starting from index 1. This could well have ‘show from’ or ‘display offset’. Thus we feed the number 5 as the 4 lines have to be skipped. If we give 4 the System process is still displayed, in case you were wondering, giving a bit of a confused logic because the 4th line is not skipped but rather excluded from the skipping. It’s better to think it in terms of the display offset.
Also the column is reordered. In this case the display is reversed as the last column is the first and vice versa.
The key to successful tokenising is to get an idea of what is the field you are looking for in that line and how many spaces have elapsed from the start of the line. Once you know the position of its occurrence, tokenising becomes easy.
PROBLEM 21: Filter out chrome.exe from the tasklist default output and skip the first 4 lines. Use the IF command in the do segment, instead of FIND in the set segment.
ANS :: for /f “tokens=1,2,3* skip=5” %i in (‘tasklist’) do @if %i==chrome.exe (echo %l %j %k %i)
Here the output of tasklist is processed. The headers are removed, the idle and dummy process names like System is removed. Further the string of chrome.exe will occur if the %i variable is read as the process name is the first column, and if chrome.exe is found then reorder the final column display of tasklist.
PROBLEM 22: Tokenise the wmic process output for chrome.exe, get the name, processid, and threadcount. Further reorder the output of wmic to THREADCOUNT, PROCESSID and NAME (reverse the order).
Thereafter change the current directory to ‘C:\OWNZ’. Use a nested FOR loop in the next loop sequence. Read the directory of the current directory recursively for all exe and dll files. Pass the output of this FOR /R loop within a FOR /F and search for the resulting list in memory for file sizes greater than 10000 bytes and display the final result as SIZE FULLPATH format.
Change back the current directory to ‘C:\TEST’.
ANS :: (for /f “tokens=1,2,3* skip=1″ %i in (‘”wmic process where name=”chrome.exe” get threadcount,name,processid”‘) do @echo %k %j %i & (cd C:\ownz\)) & (for /f “tokens=1*” %a in (‘”for /r %i in (*.exe *.dll) do @echo “%i””‘) do @if %~za GEQ 100 (echo %a %b)) & (cd C:\TEST)
Here wmic is used to get the details of chrome.exe and the threadcount, name and processed are extracted. Notice that changing the order of the fields needed will not change the order of the final output with just wmic. Thus writing get processed,name, threadcount will get the same order as the default. Thus, we parse the final output and tokenise it,and then reorder the output to out preference by simply exchanging the sequence of the token variable placeholders.
Notice how the entire wmic command is kept in single quotes (for any command) and then enclosed within double quotes for containing the complete command.
PROBLEM 23: Enumerate the owners who have started a process, use tasklist –v. Extract only the Owner column and the process name. Use 2 tokens and one wildcard for this. Check if owner is VSRM and display only the ones who aren’t. Display should be in PROCESS_NAME OWNER column format. The output should be sorted according to the process name.
ANS :: (for /f “tokens=1,8* skip=1” %i in (‘tasklist -v’) do @if NOT %j == VSRM\VSRM (@echo %i %j)) | sort
Here, we try to sort a list of processes and their extracted owners that are not the current user account. This helps flag unwanted accounts or hidden accounts that have started a process. Notice how you would use the 1st and the 8th column directly to pinpoint the location in the text output in memory.
VARIATION 1: Sort and decorate the output format. Use a few more tokens and list a few more fields.
ANS :: (for /f “tokens=1,2,8* skip=5” %i in (‘tasklist -v’) do @if NOT %k == VSRM\VSRM (@echo %j — %i %k)) | sort
Here we redecorate the output by using OwnerName – ProcessName 2 column format.
VARIATION 2: List processes containing ntdll.dll and display just the PID and the PROCESSNAME from the default output (which is quite large and displays the full list of loaded dlls in each process, further the columns are formatted in separate segments).
ANS :: (for /f “tokens=1,2,3*” %i in (‘”tasklist /m /fi “modules eq ntdll.dll” | find /i “exe””‘) do @echo %j %i)
In this case we want the output of tasklist to give us the list of processes containing the ntdll.dll but not the whole collated list. Rather we simplify the list by using find /I “exe” (I switch for case insensitive) to filter out the Process names containing that dll and echo the line containing the PID and the NAME.
PROBLEM 24: A few commands are typed and saved in a file c.txt in the current directory. Execute the commands contained in the text file. This is not a batch file.
ANS :: for /F “tokens=1*” %i in (c.txt) do %i %j
For simple non piped cmd.exe commands, simply removing the @ sign and writing the command after the do statement will execute that command from a file. Each individual command has to be in its own line for this command to work. This is not to be a counterpart to .bat files which are far more efficient, but to display the options you have if required. Basically while parsing a list, you could make a condition to simply display all the lines on the console save one line if it contains the text “notepad” then start notepad.exe. Stuff like that, wherein the conditional processing will make it more useful. This certainly has the potential to be misused in a set of benign text files.
More complex commands like nested and piped for loops can be also executed but they will run in cmd /c or cmd /k modes and then cancelling the operation becomes a pain at that point. Further the use of CTRL +C will not work as expected and thus makes the effort not really conducive to regular console based batch operations from a text file, just for kicks. Try it yourself.
NOTE : For batch files all the variables prefixed with % have to be changed to %%. Thereafter simply double clicking the .bat file should open a cmd window and carry out the instructions.
You have seen 24 instances of fooling around with FOR loops and have gained a better understanding of this less used command in cmd.exe. It is much quicker for a variety of tasks instead of heading for the C/C++ compiler to make your own version of similar algorithms, or using a 3rd party package of sorts. Much of this embedded functionality is at your fingertips if you are inclined to explore more about it. We have also taken a good look at combining various other commands and features like IF/FINDSTR/WMIC/FOR LOOP attribute extensions/NESTED LOOPS/DAISY CHAINING using PARENTHESES and the AMPERSAND operator etc. We have also gained an understanding of how to extract and format data from textual data sources to our requirements-from memory and the file system which gives us a particular flexibility of options to work with.