Page 1 of 1

for /f

Posted: 05 Sep 2011 14:03
by Exouxas
Hello dear DOS community!

I have been banging my face in the wall trying to understand this.

Does anyone have a simple explaination on how this works and what I can use it for?

Also, if this is usefull for any of my scripts that I add credits to, i will add you there and send you a neat copy of it :3

-Exouxas

Re: for /f

Posted: 05 Sep 2011 14:50
by nitt
Exouxas wrote:Hello dear DOS community!

I have been banging my face in the wall trying to understand this.

Does anyone have a simple explaination on how this works and what I can use it for?

Also, if this is usefull for any of my scripts that I add credits to, i will add you there and send you a neat copy of it :3

-Exouxas


Image

Code: Select all

for /f "tokens=1 delims= " %%a in ('tasklist /nh') do (
echo %%a
)


Now, examine the diagram. I wasn't sure what to call everything, so some things are a little goofy.

First notice the "output arguments" and the "command of output". What does the "tasklist /nh" command return? Well, that's simple. It returns something like this:

Code: Select all

System Idle Process              0 Services                   0         24 K
System                           4 Services                   0        304 K
smss.exe                       252 Services                   0        644 K
csrss.exe                      488 Services                   0      2,344 K
sqlservr.exe                  1596 Services                   0     11,196 K
dwm.exe                       1888 Console                    1     33,716 K
etc...


That's what the "tasklist /nh" line outputs. So with a "for /f" loop, our main goal is to loop through the output of a command.

See the "commands of loop? Everything in between those "()" brackets will execute for every loop. And every time it loops, it sends the results of our arguments to the "%%a" variable.

May be hard to understand, but let me explain. Our arguments are "tokens=1 delims= ". "tokens" is based off of your "delims", or "delimiters". Let's say, instead of "tasklist /nh", we say "echo bob yo". If we use "tokens=1 delims= ", then the result is

Code: Select all

bob


Why is this? Because "echo bob yo" returns a single line of "bob yo". Our "delims" defines how we want to split up each line of output. By saying "delims= ", I said to split it up by a space, or " ". And "tokens" is which part of the split you want to return. By saying "tokens=1", I said get the first split. Which is "bob". If I said "tokens=2", then it would get the second split, or "yo". Let's say I changed "delims= " to "delims=o". Then "tokens=1" would return "b" and "tokens=2" would return "b y". Because it splits them by the delimiter.

Now how this works, is it loops through each line of the output of the command. Let's pretend the output of "tasklist /nh" is only

Code: Select all

System Idle Process              0 Services                   0         24 K
System                           4 Services                   0        304 K
smss.exe                       252 Services                   0        644 K
csrss.exe                      488 Services                   0      2,344 K
sqlservr.exe                  1596 Services                   0     11,196 K
dwm.exe                       1888 Console                    1     33,716 K


Now that means when we use "tasklist /nh" the "commands of loop" commands will be run 6 times. Why? Because that's how many lines are in the output. And "for /f" loops through the output. And our arguments said to return "tokens=1 delims= ", that means we split the output by a space and then select the first token, or the first split. And so every time it loops, "%%a" holds what the arguments return. So on the third loop, where it says "csrss.exe 488 Services [...]" it only sends "csrss.exe" to "%%a" because that's what the "output arguments" tell it to do. Now for every line, "%%a" is set to something based off of the line. So the first time it loops, "%%a" is "System", the second time, it's "System" again, the third it's "smss.exe", the fourth, it's "csrss.exe", then "sqlservr.exe", then "dwm.exe". And for every time it loops (the "commands of loop"), we tell it to echo out "%%a". So we see the results. So this FOR /F loop will output:

Code: Select all

System
System
smss.exe
csrss.exe
sqlservr.exe
dwm.exe


I'm not very good at explaining things, but I hope you get the gist of it.

Re: for /f

Posted: 05 Sep 2011 17:24
by aGerman
Good explanation, nitt.
Additional ...
FOR /F is made to process text streams line by line. Such a stream could be the output of a command as well as a simple string or the content of a file.

Regards
aGerman

Re: for /f

Posted: 06 Sep 2011 12:39
by Exouxas
Thanks to both of you!

You two will surely get a spot in the credits!

I am pretty sure that I understood, but too busy to try it at the moment, but I'll get right on it when i have time.

Re: for /f

Posted: 06 Sep 2011 23:23
by Rileyh
Hi,
What is the code you first wrote supposed to do because I copied it into a batch file
and it hasn't done anything except flash the command prompt so i don't know if it worked
or not.

Rileyh

Re: for /f

Posted: 07 Sep 2011 00:03
by Exouxas
You need to edit it all so it does what you want it to.

The part where i need this is when the batch checks for an update. It takes all the files/folders and checks which one that has the highest number inside the file/folder then uses that file to update.

idea example:

updatefile12.txt:

Code: Select all

#12#
(lotsofcodetoupdate)

Re: for /f

Posted: 07 Sep 2011 11:24
by mischi
could anybody explain to me what it means, when for /f start with the following "skip=1 tokens=*"?
thanks

Re: for /f

Posted: 08 Sep 2011 10:24
by Exouxas
Does that even work? Never seen it before.

Re: for /f

Posted: 08 Sep 2011 11:13
by Ed Dyreen
'
could anybody explain to me what it means, when for /f start with the following "skip=1 tokens=*"?
thanks
Means loop the set, skip the first line and give * or any parameters

Re: for /f

Posted: 10 Sep 2011 00:49
by dbenham
Expanding on Ed's explanation of "skip=1 tokens=*" - skip can be a bit tricky because skip counts empty lines even though FOR /F ultimately discards all empty lines. So if your input stream has empty lines at the top they need to be factored into the skip computation.

The tokens=* means to preserve the entire line as one token AFTER leading delimiters are stripped. The default delimiters are <space> and <tab>. So that means the entire line will be preserved except for leading spaces and tabs.

Also, any line beginning with ; will be discarded because the default EOL character is a semicolon.

Dave Benham