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

📄 ch34_17.htm

📁 the unix power tools
💻 HTM
字号:
<HTML><!--Distributed by F --><HEAD><TITLE>[Chapter 34] 34.17 Searching for Patterns Split Across Lines </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:47: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="ch34_01.htm"TITLE="34. The sed Stream Editor"><LINKREL="prev"HREF="ch34_16.htm"TITLE="34.16 The Deliberate Scrivener "><LINKREL="next"HREF="ch34_18.htm"TITLE="34.18 Multiline Delete "></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="ch34_16.htm"TITLE="34.16 The Deliberate Scrivener "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 34.16 The Deliberate Scrivener "BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="171"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1">Chapter 34<BR>The sed Stream Editor</FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="172"><ACLASS="SECT1"HREF="ch34_18.htm"TITLE="34.18 Multiline Delete "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 34.18 Multiline Delete "BORDER="0"></A></TD></TR></TABLE>&nbsp;<HRALIGN="LEFT"WIDTH="515"TITLE="footer"></DIV><DIVCLASS="SECT1"><H2CLASS="sect1"><ACLASS="title"NAME="UPT-ART-0090">34.17 Searching for Patterns Split Across Lines </A></H2><PCLASS="para"><ACLASS="indexterm"NAME="AUTOID-39103"></A>[Article <ACLASS="xref"HREF="ch27_11.htm"TITLE="A Multiline Context grep Using sed ">27.11</A>introduced ascript called <ICLASS="filename">cgrep.sed</I>,a general-purpose, <ICLASS="filename">grep</I>-like program built with <ICLASS="filename">sed</I>.It allows you to look for one or more words that appear on one lineor across several lines.This article explains the <ICLASS="filename">sed</I> tricks thatare necessary to do this kind of thing.It gets into territory thatis essential for any advanced applications of this obscure yetwonderful editor.(Articles<ACLASS="xref"HREF="ch34_13.htm"TITLE="Hold Space: The Set-Aside Buffer ">34.13</A>through<ACLASS="xref"HREF="ch34_16.htm"TITLE="The Deliberate Scrivener ">34.16</A>have background information.) -JP]</P><PCLASS="para">Let's review the two examples from article<ACLASS="xref"HREF="ch27_11.htm"TITLE="A Multiline Context grep Using sed ">27.11</A>.The first command below finds all lines containing the word <EMCLASS="emphasis">system</EM>in the file <EMCLASS="emphasis">main.c</EM>, and shows 10 additional lines of context aboveand below each match.The second command finds all occurrences of the word &quot;awk&quot; where it isfollowed by the word &quot;perl&quot; somewhere within the next 3 lines:<ACLASS="indexterm"NAME="AUTOID-39117"></A></P><PCLASS="para"><BLOCKQUOTECLASS="screen"><PRECLASS="screen">cgrep -10 system main.ccgrep -3 &quot;awk.*perl&quot;</PRE></BLOCKQUOTE></P><PCLASS="para">Now the script, followed by an explanation of how it works:</P><PCLASS="para"><TABLECLASS="screen.co"BORDER="1"><TR><THVALIGN="TOP"><PRECLASS="calloutlist">&#13;<ACLASS="co"HREF="ch44_06.htm"TITLE="44.6 Pattern Matching in case Statements ">case</A> <ACLASS="co"HREF="ch45_28.htm"TITLE="45.28 Quick Reference: expr ">expr</A> <ACLASS="co"HREF="ch45_12.htm"TITLE="45.12 Parameter Substitution ">${?}</A> <ACLASS="co"HREF="ch44_15.htm"TITLE="44.15 Handling Command-Line Arguments in Shell Scripts ">&quot;$@&quot;</A> </PRE></TH><TDVALIGN="TOP"><PRECLASS="screen">#!/bin/sh#  cgrep - multiline context grep using sed#  Usage: cgrep [-context] pattern [file...]n=3case $1 in -[1-9]*)    n=`expr 1 - &quot;$1&quot;`    shiftesacre=${1?}; shiftsed -n &quot;    1b start    : top    \~$re~{        h; n; p; H; g        b endif    }        N        : start        //{ =; p; }    : endif    $n,\$D    b top&quot; &quot;$@&quot;</PRE></TD></TR></TABLE></P><PCLASS="para">The <EMCLASS="emphasis">sed</EM> script is embedded in a bare-bones<SPANCLASS="link">shell wrapper (<ACLASS="linkend"HREF="ch44_14.htm"TITLE="Putting awk, sed, etc., Inside Shell Scripts ">44.14</A>)</SPAN>to parse out the initial arguments because, unlike <EMCLASS="emphasis">awk</EM> and<EMCLASS="emphasis">perl</EM>, <EMCLASS="emphasis">sed</EM> cannot directly access command-line parameters.If the first argument looks like a <EMCLASS="emphasis">-context</EM> option, variable<EMCLASS="emphasis">n</EM> is reset to one more than the number of lines specified, usinga little trick&nbsp;- the argument is treated as a negative number andsubtracted from <CODECLASS="literal">1</CODE>.The pattern argument is then stored in <CODECLASS="literal">$re</CODE>, with the<CODECLASS="literal">${1?}</CODE> syntax causing the shell to abort with an error messageif no pattern was given.Any remaining arguments are passed as filenames to the <EMCLASS="emphasis">sed</EM>command.</P><PCLASS="para">So that the <CODECLASS="literal">$re</CODE> and <CODECLASS="literal">$n</CODE> parameters can be embedded,the sed script is enclosed in<SPANCLASS="link">double quotes (<ACLASS="linkend"HREF="ch08_14.htm"TITLE="Bourne Shell Quoting ">8.14</A>)</SPAN>.We use the <EMCLASS="emphasis">-n</EM> option because we don't want to print out everyline by default, and because we need to use the <CODECLASS="literal">n</CODE> commandin the script without its side effect of outputting a line.</P><PCLASS="para">The <EMCLASS="emphasis">sed</EM> script itself looks rather unstructured (it was actuallydesigned using a flowchart), but the basic algorithm is easy enoughto understand.We keep a &quot;window&quot; of <EMCLASS="emphasis">n</EM> lines in the pattern spaceand scroll this window through the input stream.If an occurrence of the pattern comes into the window, the entirewindow is printed (providing <EMCLASS="emphasis">n</EM> lines of previous context), andeach subsequent line is printed until the pattern scrolls out of viewagain (providing <EMCLASS="emphasis">n</EM> lines of following context).The sed idiom <CODECLASS="literal">N;D</CODE> is used to advance the window, with the<CODECLASS="literal">D</CODE> not kicking in until the first <EMCLASS="emphasis">n</EM> lines of input havebeen accumulated.</P><PCLASS="para">The core of the script is basically an if-then-else constructthat decides if we are currently &quot;in context.&quot;(The regular expression here is delimited by tilde (<CODECLASS="literal">~</CODE>)characters because tildes are less likely to occur in the user-suppliedpattern than slashes.)<BCLASS="emphasis.bold">If</B> we are still in context, <BCLASS="emphasis.bold">then</B> the next line ofinput is read and output, temporarily using the hold space tosave the window (and effectively doing an <CODECLASS="literal">N</CODE> in the process).<BCLASS="emphasis.bold">Else</B> we append the next input line (<CODECLASS="literal">N</CODE>) and search for thepattern again (an empty regular expression means to reuse thelast pattern).If it's now found, then the pattern must have just come into view&nbsp;- sowe print the current line number followed by the contents of thewindow.Subsequent iterations will take the &quot;then&quot; branch until the patternscrolls out of the window.</P><DIVCLASS="sect1info"><PCLASS="SECT1INFO">- <SPANCLASS="authorinitials">GU</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="ch34_16.htm"TITLE="34.16 The Deliberate Scrivener "><IMGSRC="gifs/txtpreva.gif"SRC="gifs/txtpreva.gif"ALT="Previous: 34.16 The Deliberate Scrivener "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="ch34_18.htm"TITLE="34.18 Multiline Delete "><IMGSRC="gifs/txtnexta.gif"SRC="gifs/txtnexta.gif"ALT="Next: 34.18 Multiline Delete "BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="172">34.16 The Deliberate Scrivener </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">34.18 Multiline Delete </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 &amp; 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 + -