for /f

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Exouxas
Posts: 34
Joined: 01 Sep 2011 12:52

for /f

#1 Post by Exouxas » 05 Sep 2011 14:03

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

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: for /f

#2 Post by nitt » 05 Sep 2011 14:50

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.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: for /f

#3 Post by aGerman » 05 Sep 2011 17:24

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

Exouxas
Posts: 34
Joined: 01 Sep 2011 12:52

Re: for /f

#4 Post by Exouxas » 06 Sep 2011 12:39

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.

Rileyh
Posts: 147
Joined: 01 Sep 2011 03:54
Location: Perth, Western Australia

Re: for /f

#5 Post by Rileyh » 06 Sep 2011 23:23

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

Exouxas
Posts: 34
Joined: 01 Sep 2011 12:52

Re: for /f

#6 Post by Exouxas » 07 Sep 2011 00:03

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)

mischi
Posts: 12
Joined: 24 Dec 2010 02:31

Re: for /f

#7 Post by mischi » 07 Sep 2011 11:24

could anybody explain to me what it means, when for /f start with the following "skip=1 tokens=*"?
thanks

Exouxas
Posts: 34
Joined: 01 Sep 2011 12:52

Re: for /f

#8 Post by Exouxas » 08 Sep 2011 10:24

Does that even work? Never seen it before.

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: for /f

#9 Post by Ed Dyreen » 08 Sep 2011 11:13

'
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
Last edited by Ed Dyreen on 13 Sep 2011 23:06, edited 2 times in total.

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: for /f

#10 Post by dbenham » 10 Sep 2011 00:49

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

Post Reply