old-www/LDP/Bash-Beginners-Guide/html/sect_09_01.html

514 lines
8.0 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML
><HEAD
><TITLE
>The for loop</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Bash Guide for Beginners"
HREF="index.html"><LINK
REL="UP"
TITLE="Repetitive tasks"
HREF="chap_09.html"><LINK
REL="PREVIOUS"
TITLE="Repetitive tasks"
HREF="chap_09.html"><LINK
REL="NEXT"
TITLE="The while loop"
HREF="sect_09_02.html"></HEAD
><BODY
CLASS="sect1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Bash Guide for Beginners</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="chap_09.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 9. Repetitive tasks</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="sect_09_02.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="sect_09_01"
></A
>9.1. The for loop</H1
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_09_01_01"
></A
>9.1.1. How does it work?</H2
><P
>The <B
CLASS="command"
>for</B
> loop is the first of the three shell looping constructs. This loop allows for specification of a list of values. A list of commands is executed for each value in the list.</P
><P
>The syntax for this loop is:</P
><P
><B
CLASS="command"
>for <TT
CLASS="varname"
>NAME</TT
> [in LIST ]; do COMMANDS; done</B
> </P
><P
>If <B
CLASS="command"
>[in LIST]</B
> is not present, it is replaced with <B
CLASS="command"
>in <TT
CLASS="varname"
>$@</TT
></B
> and <B
CLASS="command"
>for</B
> executes the <B
CLASS="command"
>COMMANDS</B
> once for each positional parameter that is set (see <A
HREF="sect_03_02.html#sect_03_02_05"
>Section 3.2.5</A
> and <A
HREF="sect_07_02.html#sect_07_02_01_02"
>Section 7.2.1.2</A
>).</P
><P
>The return status is the exit status of the last command that executes. If no commands are executed because <TT
CLASS="varname"
>LIST</TT
> does not expand to any items, the return status is zero.</P
><P
><TT
CLASS="varname"
>NAME</TT
> can be any variable name, although <TT
CLASS="varname"
>i</TT
> is used very often. <TT
CLASS="varname"
>LIST</TT
> can be any list of words, strings or numbers, which can be literal or generated by any command. The <B
CLASS="command"
>COMMANDS</B
> to execute can also be any operating system commands, script, program or shell statement. The first time through the loop, <TT
CLASS="varname"
>NAME</TT
> is set to the first item in <TT
CLASS="varname"
>LIST</TT
>. The second time, its value is set to the second item in the list, and so on. The loop terminates when <TT
CLASS="varname"
>NAME</TT
> has taken on each of the values from <TT
CLASS="varname"
>LIST</TT
> and no items are left in <TT
CLASS="varname"
>LIST</TT
>.</P
></DIV
><DIV
CLASS="sect2"
><H2
CLASS="sect2"
><A
NAME="sect_09_01_02"
></A
>9.1.2. Examples</H2
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_09_01_02_03"
></A
>9.1.2.1. Using command substitution for specifying LIST items</H3
><P
>The first is a command line example, demonstrating the use of a <B
CLASS="command"
>for</B
> loop that makes a backup copy of each <TT
CLASS="filename"
>.xml</TT
> file. After issuing the command, it is safe to start working on your sources:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>[carol@octarine ~/articles]</TT
> <B
CLASS="command"
>ls <TT
CLASS="filename"
>*.xml</TT
></B
>
file1.xml file2.xml file3.xml
<TT
CLASS="prompt"
>[carol@octarine ~/articles]</TT
> <B
CLASS="command"
>ls <TT
CLASS="filename"
>*.xml</TT
> &#62; <TT
CLASS="filename"
>list</TT
></B
>
<TT
CLASS="prompt"
>[carol@octarine ~/articles]</TT
> <B
CLASS="command"
>for <TT
CLASS="varname"
>i</TT
> in <TT
CLASS="parameter"
><I
>`cat list`</I
></TT
>; do cp <TT
CLASS="filename"
>"$i" "$i".bak</TT
> ; done</B
>
<TT
CLASS="prompt"
>[carol@octarine ~/articles]</TT
> <B
CLASS="command"
>ls <TT
CLASS="filename"
>*.xml*</TT
></B
>
file1.xml file1.xml.bak file2.xml file2.xml.bak file3.xml file3.xml.bak
</PRE
></FONT
></TD
></TR
></TABLE
><P
>This one lists the files in <TT
CLASS="filename"
>/sbin</TT
> that are just plain text files, and possibly scripts:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<B
CLASS="command"
>for <TT
CLASS="varname"
>i</TT
> in <TT
CLASS="parameter"
><I
>`ls /sbin`</I
></TT
>; do file <TT
CLASS="filename"
>/sbin/$i</TT
> | grep <TT
CLASS="parameter"
><I
>ASCII</I
></TT
>; done</B
>
</PRE
></FONT
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="sect3"
><H3
CLASS="sect3"
><A
NAME="sect_09_01_02_02"
></A
>9.1.2.2. Using the content of a variable to specify LIST items</H3
><P
>The following is a specific application script for converting HTML files, compliant with a certain scheme, to PHP files. The conversion is done by taking out the first 25 and the last 21 lines, replacing these with two PHP tags that provide header and footer lines:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;<TT
CLASS="prompt"
>[carol@octarine ~/html]</TT
> <B
CLASS="command"
>cat <TT
CLASS="filename"
>html2php.sh</TT
></B
>
#!/bin/bash
# specific conversion script for my html files to php
LIST="$(ls *.html)"
for i in "$LIST"; do
NEWNAME=$(ls "$i" | sed -e 's/html/php/')
cat beginfile &#62; "$NEWNAME"
cat "$i" | sed -e '1,25d' | tac | sed -e '1,21d'| tac &#62;&#62; "$NEWNAME"
cat endfile &#62;&#62; "$NEWNAME"
done
</PRE
></FONT
></TD
></TR
></TABLE
><P
>Since we don't do a line count here, there is no way of knowing the line number from which to start deleting lines until reaching the end. The problem is solved using <B
CLASS="command"
>tac</B
>, which reverses the lines in a file.</P
><DIV
CLASS="tip"
><P
></P
><TABLE
CLASS="tip"
WIDTH="100%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/tip.gif"
HSPACE="5"
ALT="Tip"></TD
><TH
ALIGN="LEFT"
VALIGN="CENTER"
><B
>The basename command</B
></TH
></TR
><TR
><TD
>&nbsp;</TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>Instead of using <B
CLASS="command"
>sed</B
> to replace the <TT
CLASS="filename"
>html</TT
> suffix with <TT
CLASS="filename"
>php</TT
>, it would be cleaner to use the <B
CLASS="command"
>basename</B
> command. Read the man page for more info.</P
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="warning"
><P
></P
><TABLE
CLASS="warning"
WIDTH="100%"
BORDER="0"
><TR
><TD
WIDTH="25"
ALIGN="CENTER"
VALIGN="TOP"
><IMG
SRC="../images/warning.gif"
HSPACE="5"
ALT="Warning"></TD
><TH
ALIGN="LEFT"
VALIGN="CENTER"
><B
>Odd characters</B
></TH
></TR
><TR
><TD
>&nbsp;</TD
><TD
ALIGN="LEFT"
VALIGN="TOP"
><P
>You will run into problems if the list expands to file names containing spaces and other irregular characters. A more ideal construct to obtain the list would be to use the shell's globbing feature, like this:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;for i in $PATHNAME/*; do
commands
done
</PRE
></FONT
></TD
></TR
></TABLE
></TD
></TR
></TABLE
></DIV
></DIV
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="chap_09.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="sect_09_02.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Repetitive tasks</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="chap_09.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>The while loop</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>