📄 ch09_11.htm
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 9] 9.11 Repeating a Command with a foreach Loop </TITLE><METANAME="DC.title"CONTENT="UNIX Power Tools"><METANAME="DC.creator"CONTENT="Jerry Peek, Tim O'Reilly & Mike Loukides"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1998-08-04T21:35:03Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-260-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch09_01.htm"TITLE="9. Saving Time on the Command Line"><LINKREL="prev"HREF="ch09_10.htm"TITLE="9.10 Filename Completion Isn't Always the Answer "><LINKREL="next"HREF="ch09_12.htm"TITLE="9.12 The Bourne Shell for Loop "></HEAD><BODYBGCOLOR="#FFFFFF"TEXT="#000000"><DIVCLASS="htmlnav"><H1><IMGSRC="gifs/smbanner.gif"ALT="UNIX Power Tools"USEMAP="#srchmap"BORDER="0"></H1><MAPNAME="srchmap"><AREASHAPE="RECT"COORDS="0,0,466,58"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="467,0,514,18"HREF="jobjects/fsearch.htm"ALT="Search this book"></MAP><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch09_10.htm"TITLE="9.10 Filename Completion Isn't Always the Answer "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 9.10 Filename Completion Isn't Always the Answer "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 9<BR>Saving Time on the Command Line</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch09_12.htm"TITLE="9.12 The Bourne Shell for Loop "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 9.12 The Bourne Shell for Loop "BORDER="0"></A></TD></TR></TABLE> <HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-7020">9.11 Repeating a Command with a foreach Loop </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-10290"></A><ACLASS="indexterm"NAME="AUTOID-10293"></A><ACLASS="indexterm"NAME="AUTOID-10295"></A>When some people need to repeat a command on several files, the first thingthey think of is C shell<SPANCLASS="link">history (<ACLASS="linkend"HREF="ch11_05.htm"TITLE="My Favorite Is ^^ ">11.5</A>)</SPAN>:</P><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist"><ACLASS="co"HREF="ch25_07.htm"TITLE="25.7 Show Non-Printing Characters with cat -v or od -c ">-v</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen">% <CODECLASS="userinput"><B>cat -t -v /usr/fran/report | pg</B></CODE> ...% <CODECLASS="userinput"><B>^fran/report^rob/file3</B></CODE>cat -t -v /usr/rob/file3 | pg ...% <CODECLASS="userinput"><B>^3^21</B></CODE>cat -t -v /usr/rob/file21 | pg ...%</PRE></TD></TR></TABLE></P><PCLASS="para">That kind of thing can be easier with the C shell's <EMCLASS="emphasis">foreach</EM> loop.(In the Bourne and Korn shells, use a<SPANCLASS="link"><EMCLASS="emphasis">for</EM> (<ACLASS="linkend"HREF="ch09_12.htm"TITLE="The Bourne Shell for Loop ">9.12</A>)</SPAN>loop.)You give the loop a list of the words that will change each time the commandline is run.In this example, it's a list of filenames.The loop will step through the words, one by one, storing a word into a<SPANCLASS="link">shell variable (<ACLASS="linkend"HREF="ch06_08.htm"TITLE="Shell Variables ">6.8</A>)</SPAN>,then running the command(s).The loop goes on until it has read all the words.For example:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>foreach file (/usr/fran/report /usr/rob/file3 /usr/rob/file21)</B></CODE>? <CODECLASS="userinput"><B>cat -t -v $file | pg</B></CODE>? <CODECLASS="userinput"><B>end</B></CODE> ...<EMCLASS="emphasis">Shell runs cat -t -v /usr/fran/report | pg</EM>... ...<EMCLASS="emphasis">Shell runs cat -t -v /usr/rob/file3 | pg</EM>... ...<EMCLASS="emphasis">Shell runs cat -t -v /usr/rob/file21 | pg</EM>...%</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-10319"></A>The question marks (<CODECLASS="literal">?</CODE>) are<SPANCLASS="link">secondary prompts (<ACLASS="linkend"HREF="ch09_13.htm"TITLE="Multiline Commands, Secondary Prompts ">9.13</A>)</SPAN>;the C shell will keep printing them until you type the command <EMCLASS="emphasis">end</EM>.Then the loop runs.</P><PCLASS="para">The list between the parentheses doesn't have to be filenames.Among other things, you can use<SPANCLASS="link">wildcards (<ACLASS="linkend"HREF="ch01_16.htm"TITLE="Wildcards ">1.16</A>)</SPAN>,<SPANCLASS="link">backquotes (<ACLASS="linkend"HREF="ch09_16.htm"TITLE="Command Substitution ">9.16</A>)</SPAN>(command substitution),<SPANCLASS="link">variables (<ACLASS="linkend"HREF="ch06_08.htm"TITLE="Shell Variables ">6.8</A>, <ACLASS="linkend"HREF="ch06_01.htm#UPT-ART-1170"TITLE="What Environment Variables Are Good For ">6.1</A>)</SPAN>,and the C shell's handy<ACLASS="indexterm"NAME="AUTOID-10329"></A><SPANCLASS="link">curly brace (<CODECLASS="literal">{}</CODE>) operators (<ACLASS="linkend"HREF="ch09_05.htm"TITLE="Build Strings with { } ">9.5</A>)</SPAN>.For example, you could have typed the above loop this way:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>foreach file (/usr/fran/report /usr/rob/file{3,21})</B></CODE>? <CODECLASS="userinput"><B>cat -t -v $file | pg</B></CODE>? <CODECLASS="userinput"><B>end</B></CODE></PRE></BLOCKQUOTE></P><PCLASS="para">If you want the loop to stop before or after running each command, add the Cshell operator <CODECLASS="literal">$<</CODE>.It reads keyboard input and waits for a RETURN.In this case, you can probably ignorethe input; you'll use <CODECLASS="literal">$<</CODE> tomake the loop wait.For example, to make the loop above prompt before each command line:</P><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist"> <ACLASS="co"HREF="ch06_08.htm"TITLE="6.8 Shell Variables ">set</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen">% <CODECLASS="userinput"><B>foreach file (/usr/fran/report /usr/rob/file{3,21})</B></CODE>? <CODECLASS="userinput"><B>echo -n "Press RETURN to see $file-"</B></CODE>? <CODECLASS="userinput"><B>set x="$<"</B></CODE>? <CODECLASS="userinput"><B>cat -t -v $file | pg</B></CODE>? <CODECLASS="userinput"><B>end</B></CODE>Press RETURN to see /usr/fran/report- <KBDCLASS="keycap">[RETURN]</KBD> <EMCLASS="emphasis">Shell runs cat -t -v /usr/fran/report | pg</EM>...Press RETURN to see /usr/rob/file3- <KBDCLASS="keycap">[RETURN]</KBD> <EMCLASS="emphasis">Shell runs cat -t -v /usr/rob/file3 | pg</EM>...Press RETURN to see /usr/rob/file21- <KBDCLASS="keycap">[RETURN]</KBD> <EMCLASS="emphasis">Shell runs cat -t -v /usr/rob/file21 | pg</EM>...</PRE></TD></TR></TABLE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-10357"></A><ACLASS="indexterm"NAME="AUTOID-10361"></A>The loop parameters don't need to be filenames.For instance, you could send a personalized<SPANCLASS="link">mail (<ACLASS="linkend"HREF="ch01_33.htm"TITLE="UNIX Networking and Communications ">1.33</A>)</SPAN>message to five peoplethis way:[1]</P><BLOCKQUOTECLASS="footnote"><PCLASS="para">[1] If you're sending lots of mail messages with a loop, your system mailermay get overloaded.In that case, it's a good idea to put a command like<SPANCLASS="link"><CODECLASS="literal">sleep</CODE> <CODECLASS="literal">5</CODE> (<ACLASS="linkend"HREF="ch40_02.htm"TITLE="Waiting a Little While: sleep ">40.2</A>)</SPAN>on a separate line before the <CODECLASS="literal">end</CODE>.That will give the mailer five seconds to send each message.</P></BLOCKQUOTE><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist"> <ACLASS="co"HREF="ch13_13.htm"TITLE='13.13 The "Filename" - '>cat -</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen">% <CODECLASS="userinput"><B>foreach person (John Cathy Agnes Brett Elma)</B></CODE>? <CODECLASS="userinput"><B>echo "Dear $person," | cat - formletter | mail $person</B></CODE>? <CODECLASS="userinput"><B>end</B></CODE></PRE></TD></TR></TABLE></P><PCLASS="para">The first line of the first letter will be "Dear John,"; the secondletter "Dear Cathy,"; and so on.</P><PCLASS="para">Want to take this idea further?It's a part of<SPANCLASS="link">shell programming (<ACLASS="linkend"HREF="ch44_01.htm#UPT-ART-0065"TITLE="Everyone Should Learn Some Shell Programming ">44.1</A>)</SPAN>.I usually<SPANCLASS="link">don't recommend (<ACLASS="linkend"HREF="ch47_02.htm"TITLE="C Shell Programming Considered Harmful ">47.2</A>)</SPAN>shell programming with the C shell,but this is a handy technique to use interactively.</P><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">JP</SPAN></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><TABLEWIDTH="515"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch09_10.htm"TITLE="9.10 Filename Completion Isn't Always the Answer "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 9.10 Filename Completion Isn't Always the Answer "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="book"HREF="index.htm"TITLE="UNIX Power Tools"><IMGSRC="gifs/txthome.gif"SRC="gifs/txthome.gif"ALT="UNIX Power Tools"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch09_12.htm"TITLE="9.12 The Bourne Shell for Loop "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 9.12 The Bourne Shell for Loop "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">9.10 Filename Completion Isn't Always the Answer </TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><ACLASS="index"HREF="index/idx_0.htm"TITLE="Book Index"><IMGSRC="gifs/index.gif"SRC="gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172">9.12 The Bourne Shell for Loop </TD></TR></TABLE><HRALIGN="LEFT"WIDTH="515"TITLE="footer"><IMGSRC="gifs/smnavbar.gif"SRC="gifs/smnavbar.gif"USEMAP="#map"BORDER="0"ALT="The UNIX CD Bookshelf Navigation"><MAPNAME="map"><AREASHAPE="RECT"COORDS="0,0,73,21"HREF="../index.htm"ALT="The UNIX CD Bookshelf"><AREASHAPE="RECT"COORDS="74,0,163,21"HREF="index.htm"ALT="UNIX Power Tools"><AREASHAPE="RECT"COORDS="164,0,257,21"HREF="../unixnut/index.htm"ALT="UNIX in a Nutshell"><AREASHAPE="RECT"COORDS="258,0,321,21"HREF="../vi/index.htm"ALT="Learning the vi Editor"><AREASHAPE="RECT"COORDS="322,0,378,21"HREF="../sedawk/index.htm"ALT="sed & awk"><AREASHAPE="RECT"COORDS="379,0,438,21"HREF="../ksh/index.htm"ALT="Learning the Korn Shell"><AREASHAPE="RECT"COORDS="439,0,514,21"HREF="../lrnunix/index.htm"ALT="Learning the UNIX Operating System"></MAP></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -