⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch45_30.htm

📁 the unix power tools
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 45] 45.30 Grabbing Parts of a String </TITLE><METANAME="DC.title"CONTENT="UNIX Power Tools"><METANAME="DC.creator"CONTENT="Jerry Peek, Tim O'Reilly &amp; Mike Loukides"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1998-08-04T21:55:04Z"><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="ch45_01.htm"TITLE="45. Shell Programming for the Initiated"><LINKREL="prev"HREF="ch45_29.htm"TITLE="45.29 Testing Characters in a String with expr "><LINKREL="next"HREF="ch45_31.htm"TITLE="45.31 Nested Command Substitution "></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="ch45_29.htm"TITLE="45.29 Testing Characters in a String with expr "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 45.29 Testing Characters in a String with expr "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 45<BR>Shell Programming for the Initiated</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch45_31.htm"TITLE="45.31 Nested Command Substitution "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 45.31 Nested Command Substitution "BORDER="0"></A></TD></TR></TABLE>&nbsp;<HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-0232">45.30 Grabbing Parts of a String </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54621"></A><ACLASS="indexterm"NAME="AUTOID-54624"></A><ACLASS="indexterm"NAME="AUTOID-54627"></A>How can you parse (split, search) a string of text to find the lastword, the second column, and so on?There are a lot of different ways.Pick the one that works best for you&nbsp;- or invent another one!(UNIX has slots of ways to work with strings of text.)</P><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-232-SECT-1.1">45.30.1 Matching with expr </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54633"></A><ACLASS="indexterm"NAME="AUTOID-54636"></A><ACLASS="indexterm"NAME="AUTOID-54639"></A><ACLASS="indexterm"NAME="AUTOID-54642"></A><ACLASS="indexterm"NAME="AUTOID-54645"></A><ACLASS="indexterm"NAME="AUTOID-54648"></A><ACLASS="indexterm"NAME="AUTOID-54652"></A>The<SPANCLASS="link"><EMCLASS="emphasis">expr</EM> command (<ACLASS="linkend"HREF="ch45_28.htm"TITLE="Quick Reference: expr ">45.28</A>)</SPAN>can grab part of a string with a regular expression.The example below is from a shell script whose last command-line argumentis a filename.The two commands below use <EMCLASS="emphasis">expr</EM> to grab the last argument and allarguments except the last one.The <CODECLASS="literal">&quot;$*&quot;</CODE> gives <EMCLASS="emphasis">expr</EM> a list of all command-line argumentsin a single word.(Using<SPANCLASS="link"><CODECLASS="literal">&quot;$@&quot;</CODE> (<ACLASS="linkend"HREF="ch44_15.htm"TITLE="Handling Command-Line Arguments in Shell Scripts ">44.15</A>)</SPAN>here wouldn't work because it gives individually quoted arguments.<EMCLASS="emphasis">expr</EM> needs all arguments in one word.)</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">last=`expr &quot;$*&quot; : '.* \(.*\)'`    # LAST ARGUMENTfirst=`expr &quot;$*&quot; : '\(.*\) .*'`    # ALL BUT LAST ARGUMENT</PRE></BLOCKQUOTE></P><PCLASS="para">Let's look at the regular expression that gets the last word.The leading part of the expression, <CODECLASS="literal">.*&nbsp;</CODE>, matches as manycharacters as it can, followed by a space.This includes all words up to and including the last space.After that, the end of the expression, <CODECLASS="literal">\(.*\)</CODE>, matches thelast word.</P><PCLASS="para">The regular expression that grabs the first words is the same as theprevious one&nbsp;- but I've moved the <CODECLASS="literal">\(&nbsp;\)</CODE> pair.Now it grabs all words up to but not including the last space.The end of the regular expression, <CODECLASS="literal">&nbsp;.*</CODE>, matches the last spaceand last word&nbsp;- and <EMCLASS="emphasis">expr</EM> ignores them.So the final <CODECLASS="literal">.*</CODE> really isn't needed here (though the space is).I've included that final <CODECLASS="literal">.*</CODE> because it follows from the firstexample.</P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54676"></A><ACLASS="indexterm"NAME="AUTOID-54679"></A><EMCLASS="emphasis">expr</EM> is great when you want to split a string into just two parts.The <CODECLASS="literal">.*</CODE> also makes <EMCLASS="emphasis">expr</EM> good for skipping a variable numberof words when you don't know how many words a string will have.But <EMCLASS="emphasis">expr</EM> is lousy for getting, say, the fourth word in a string.And it's almost useless for handling more than one line of text at a time.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-232-SECT-1.2">45.30.2 Using echo with awk, colrm, or cut </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54689"></A><ACLASS="indexterm"NAME="AUTOID-54692"></A><ACLASS="indexterm"NAME="AUTOID-54695"></A><ACLASS="indexterm"NAME="AUTOID-54698"></A><ACLASS="indexterm"NAME="AUTOID-54701"></A><ACLASS="indexterm"NAME="AUTOID-54704"></A><ACLASS="indexterm"NAME="AUTOID-54707"></A><EMCLASS="emphasis">awk</EM>can split lines into words.But <EMCLASS="emphasis">awk</EM> has a lot of overhead and can take some time to execute,especially on a busy system.The<SPANCLASS="link"><EMCLASS="emphasis">cut</EM> (<ACLASS="linkend"HREF="ch35_14.htm"TITLE="Cutting Columns or Fields with cut ">35.14</A>)</SPAN>and<SPANCLASS="link"><EMCLASS="emphasis">colrm</EM> (<ACLASS="linkend"HREF="ch35_15.htm"TITLE="Cutting Columns with colrm ">35.15</A>)</SPAN>commands start more quickly than <EMCLASS="emphasis">awk</EM> but they can't do as much.</P><PCLASS="para">All of those utilities are designed to handle multiple lines of text.You can tell <EMCLASS="emphasis">awk</EM> to handle a single line with its pattern-matchingoperators and its <EMCLASS="emphasis">NR</EM> variable.You can also run those utilities with a single line of text, fed to thestandard input through a pipe from<SPANCLASS="link"><EMCLASS="emphasis">echo</EM> (<ACLASS="linkend"HREF="ch08_06.htm"TITLE="Output Command-Line Arguments ">8.6</A>)</SPAN>.For example, to get the third field from a colon-separated string:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">string=&quot;this:is:just:a:dummy:string&quot;field3_awk=`echo &quot;$string&quot; | awk -F: '{print $3}'`field3_cut=`echo &quot;$string&quot; | cut -d: -f3`</PRE></BLOCKQUOTE></P><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54725"></A>Let's combine two <EMCLASS="emphasis">echo</EM> commands.One sends text to <EMCLASS="emphasis">awk</EM>, <EMCLASS="emphasis">cut</EM>, or <EMCLASS="emphasis">colrm</EM> through a pipe;the utility ignores all the text from columns 1-24, then prints columns 25to the end of the variable <EMCLASS="emphasis">text</EM>.The outer <EMCLASS="emphasis">echo</EM> prints <EMCLASS="emphasis">The answer is</EM> and that answer.Notice that the inner double quotes are escaped with backslashesto keep the Bourne shell from interpreting them before the inner<EMCLASS="emphasis">echo</EM> runs:</P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">echo &quot;The answer is `echo \&quot;$text\&quot; | awk '{print substr($0,25)}'`&quot;echo &quot;The answer is `echo \&quot;$text\&quot; | cut -c25-`&quot;echo &quot;The answer is `echo \&quot;$text\&quot; | colrm 1 24`&quot;</PRE></BLOCKQUOTE></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="UPT-ART-232-SECT-1.3">45.30.3 Using set </A></H3><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-54741"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -