Bash for: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
 
(34 intermediate revisions by the same user not shown)
Line 1: Line 1:
=External=
* http://ss64.com/bash/for.html
=Internal=
=Internal=


* [[bash#Built-In_Commands|bash]]
* [[bash#Built-In_Commands|bash]]


=Overview=


The <tt>for</tt> built-in command expand ''words'', and execute ''commands'' once for each member in the resultant list, with ''i'' bound to the current member.


<pre>
  for i in words; do commands; done
</pre>


!!!bash for
Alternatively, for:
 
 
!!!Internal


|[bash]
<pre>
  for i do commands; done
</pre>


''commands'' executes for each positional parameter (as if <tt>in "$@"</tt> had been specified.


!!!Overview
Yes another alternative form:


{{{
<pre>
   
    for i in words; do commands; done
 
}}}
 
If the keyword "in" is not present, {{for}} will iterate through positional parameters.
 
Alternative form:
 
{{{
     for (( i=0; i<${#names[@]}; i++ )); do
     for (( i=0; i<${#names[@]}; i++ )); do
         local name=${names[${i}]}
         local name=${names[${i}]}
         echo "${name}"
         echo "${name}"
     done
     done
}}}
</pre>


!!!Iterating through $1, $2, $3 ...
=Iterating through $1, $2, $3 ...=


{{{
==The Simple Version==
 
<pre>
     for i do
     for i do
         echo ${i}
         echo ${i}
     done
     done
}}}
</pre>


!!!Iterating through a space separated list
==Using the Argument Array==


<font color=red>TODO</font>


{{{
=Iterating through a space separated list=


<pre>
     s="a b c"
     s="a b c"
     for i in ${s}
     for i in ${s}
         do
         do
             echo ${i}
             echo ${i}
         done
         done
}}}
</pre>


or
or


{{{
<pre>
    s="a b c"
    for i in ${s}; do echo ${i}; done
</pre>
 
Note the use of ";"
 
=Iterating over Lines in the Same bash Process=


    s="a b c"
<syntaxhighlight lang='bash'>
IFS="$(printf '\n\r')"
for line in $(cat ./file.txt); do
  echo "${line}"
done
IFS="$(printf ' \t\n')"
</syntaxhighlight>
 
{{Warn|'''Note 1''' Be careful when setting IFS before a <tt>for</tt> loop, even if you restore the default value after the loop: everything inside the loop will use the non-standard IFS value and it may not work as expected.<br><br>For more details on <tt>IFS</tt> and possible pitfalls while using it, see [[Bash_Built-In_Variables#IFS|IFS]].}}
 
{{Warn|'''Note 2''' This method does not work very well with large files. The content of the file will be first buffered in memory so the loop will appear irresponsive, at least for a while.}}
 
=Iterating over a File List=
 
Use a [[Bash Concepts#Globbing|globbing]] expression after <tt>in</tt> and the shell will replace it with the list of files matching the expression:


    for i in ${s}; do echo ${i}; done
<syntaxhighlight lang='bash'>
for f in dir/B*; do
    echo ${f}
done
</syntaxhighlight>


}}}
If file names match, the replacement closely matches the expression (example "<tt>dir/BMW.txt dir/Bentley.txt</tt>").


Note the use of ";"
In case no filename match, the for body is executed with he literal expression ("<tt>dir/B*</tt>" in the example above).


=Iterating over a ps Output=


__Referenced by:__\\
<syntaxhighlight lang='bash'>
[{INSERT com.ecyrd.jspwiki.plugin.ReferringPagesPlugin WHERE max=20, maxwidth=50}]
IFS="$(printf '\n\r')"
for proc_details in $(ps -ef | grep "..." | grep -v grep); do
    echo "${proc_details}"
done
IFS="$(printf ' \t\n')"
</syntaxhighlight>

Latest revision as of 22:22, 18 May 2021

External

Internal

Overview

The for built-in command expand words, and execute commands once for each member in the resultant list, with i bound to the current member.

   for i in words; do commands; done

Alternatively, for:

   for i do commands; done

commands executes for each positional parameter (as if in "$@" had been specified.

Yes another alternative form:

    for (( i=0; i<${#names[@]}; i++ )); do
        local name=${names[${i}]}
        echo "${name}"
    done

Iterating through $1, $2, $3 ...

The Simple Version

     for i do
         echo ${i}
     done

Using the Argument Array

TODO

Iterating through a space separated list

    s="a b c"
    for i in ${s}
        do
            echo ${i}
        done

or

     s="a b c"
     for i in ${s}; do echo ${i}; done

Note the use of ";"

Iterating over Lines in the Same bash Process

IFS="$(printf '\n\r')"
for line in $(cat ./file.txt); do
   echo "${line}"
done
IFS="$(printf ' \t\n')"

Note 1 Be careful when setting IFS before a for loop, even if you restore the default value after the loop: everything inside the loop will use the non-standard IFS value and it may not work as expected.

For more details on IFS and possible pitfalls while using it, see IFS.


Note 2 This method does not work very well with large files. The content of the file will be first buffered in memory so the loop will appear irresponsive, at least for a while.

Iterating over a File List

Use a globbing expression after in and the shell will replace it with the list of files matching the expression:

for f in dir/B*; do
    echo ${f}
done

If file names match, the replacement closely matches the expression (example "dir/BMW.txt dir/Bentley.txt").

In case no filename match, the for body is executed with he literal expression ("dir/B*" in the example above).

Iterating over a ps Output

IFS="$(printf '\n\r')"
for proc_details in $(ps -ef | grep "..." | grep -v grep); do
    echo "${proc_details}"
done
IFS="$(printf ' \t\n')"