📄 ch35_21.htm
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 35] 35.21 Using IFS to Split Strings </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:48:27Z"><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="ch35_01.htm"TITLE="35. You Can't Quite Call This Editing"><LINKREL="prev"HREF="ch35_20.htm"TITLE="35.20 Quick Reference: uniq "><LINKREL="next"HREF="ch35_22.htm"TITLE="35.22 Straightening Jagged Columns "></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="ch35_20.htm"TITLE="35.20 Quick Reference: uniq "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 35.20 Quick Reference: uniq "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 35<BR>You Can't Quite Call This Editing</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch35_22.htm"TITLE="35.22 Straightening Jagged Columns "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 35.22 Straightening Jagged Columns "BORDER="0"></A></TD></TR></TABLE> <HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-0191">35.21 Using IFS to Split Strings </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-41276"></A>It might not be obvious why the Bourne shellhas an <EMCLASS="emphasis">IFS</EM> (internal field separator) shell variable.By default, it holds three characters: SPACE, TAB, and NEWLINE.These are the places that the shell parses command lines.So what?</P><PCLASS="para">If you have a line of text - say, from a database - and you want to split itinto fields, the <EMCLASS="emphasis">IFS</EM> variable can help.Put the field separator into <EMCLASS="emphasis">IFS</EM> temporarily, use the shell's<SPANCLASS="link"><EMCLASS="emphasis">set</EM> (<ACLASS="linkend"HREF="ch44_19.htm"TITLE="The Bourne Shell set Command ">44.19</A>)</SPAN>command to store the fields in command-line parameters; then restore the old<EMCLASS="emphasis">IFS</EM>.</P><PCLASS="para">For example, the chunk of a shell script below gets current terminalsettings from<SPANCLASS="link"><EMCLASS="emphasis">stty -g</EM> (<ACLASS="linkend"HREF="ch42_04.htm"TITLE="Checklist for Resetting a Messed Up Terminal ">42.4</A>)</SPAN>,which looks like this:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">2506:5:bf:8a3b:3:1c:8:15:4:0:0:0:11:13:1a:19:12:f:17:16:0:0</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-41291"></A>The shell parses the line returned from <EMCLASS="emphasis">stty</EM> by the<SPANCLASS="link">backquotes (<ACLASS="linkend"HREF="ch09_16.htm"TITLE="Command Substitution ">9.16</A>)</SPAN>.It stores <EMCLASS="emphasis">x</EM> in <CODECLASS="literal">$1</CODE>.This trick stops errors if <EMCLASS="emphasis">stty</EM> failsfor some reason - without the <EMCLASS="emphasis">x</EM>, if <EMCLASS="emphasis">stty</EM> made no standard output,the shell's <EMCLASS="emphasis">set</EM> command would print a list of all shell variables.Then <EMCLASS="emphasis">2506</EM> goes into <CODECLASS="literal">$2</CODE>, <EMCLASS="emphasis">5</EM> into <CODECLASS="literal">$3</CODE>,and so on.The original Bourne shell can only handle nine parameters (through<CODECLASS="literal">$9</CODE>); if your input lines may have more than nine fields, thisisn't a good technique.But this script uses the Korn shell, which (along with <EMCLASS="emphasis">bash</EM>)doesn't have that limit.</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">#!/bin/ksholdifs="$IFS"# Change IFS to a colon:IFS=:# Put x in $1, stty -g output in $2 thru ${23}:set x `stty -g`IFS="$oldifs"# Window size is in 16th field (not counting the first "x"):echo "Your window has ${17} rows."</PRE></BLOCKQUOTE></P><PCLASS="para">Because you don't need a subprocess to parse the output of <EMCLASS="emphasis">stty</EM>, thiscan be faster than using an external command like<SPANCLASS="link"><EMCLASS="emphasis">cut</EM> (<ACLASS="linkend"HREF="ch35_14.htm"TITLE="Cutting Columns or Fields with cut ">35.14</A>)</SPAN>or<SPANCLASS="link"><EMCLASS="emphasis">awk</EM> (<ACLASS="linkend"HREF="ch33_11.htm"TITLE="Quick Reference: awk ">33.11</A>)</SPAN>.</P><PCLASS="para">There are places where <EMCLASS="emphasis">IFS</EM> can't be used because the shellseparates command lines at spaces before it splitsat <EMCLASS="emphasis">IFS</EM>.It doesn't split the results of variable substitution or<SPANCLASS="link">command substitution (<ACLASS="linkend"HREF="ch09_16.htm"TITLE="Command Substitution ">9.16</A>)</SPAN>at spaces, though.Here's an example - three different ways to parse a line from<EMCLASS="emphasis">/etc/passwd</EM>:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">% <CODECLASS="userinput"><B>cat splitter</B></CODE>#!/bin/shIFS=:line='larry:Vk9skS323kd4q:985:100:Larry Smith:/u/larry:/bin/tcsh'set x $lineecho "case 1: \$6 is '$6'"set x `grep larry /etc/passwd`echo "case 2: \$6 is '$6'"set x larry:Vk9skS323kd4q:985:100:Larry Smith:/u/larry:/bin/tcshecho "case 3: \$6 is '$6'"% <CODECLASS="userinput"><B>./splitter</B></CODE>case 1: $6 is 'Larry Smith'case 2: $6 is 'Larry Smith'case 3: $6 is 'Larry'</PRE></BLOCKQUOTE></P><PCLASS="para">Case 1 used variable substitution and case 2 used commandsubstitution; the sixth field contained the space.In case 3, though, with the colons on the command line,the sixth field was split:<CODECLASS="literal">$6</CODE> became <EMCLASS="emphasis">Larry</EM> and <CODECLASS="literal">$7</CODE> was <EMCLASS="emphasis">Smith</EM>.Another problem would have come up if any of the fields hadbeen empty (as in <CODECLASS="literal">larry::985:100:</CODE><EMCLASS="emphasis">etc...</EM>)-theshell would "eat" the empty field and <CODECLASS="literal">$6</CODE> would contain<EMCLASS="emphasis">/u/larry</EM>.Using <EMCLASS="emphasis">sed</EM> with its<SPANCLASS="link">escaped parentheses (<ACLASS="linkend"HREF="ch34_10.htm"TITLE="Referencing Portions of a Search String ">34.10</A>)</SPAN>to do the searching and the parsing could solve the last two problems.</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="ch35_20.htm"TITLE="35.20 Quick Reference: uniq "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 35.20 Quick Reference: uniq "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="ch35_22.htm"TITLE="35.22 Straightening Jagged Columns "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 35.22 Straightening Jagged Columns "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">35.20 Quick Reference: uniq </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">35.22 Straightening Jagged Columns </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 + -