textproc.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 3,421 行 · 第 1/5 页
HTML
3,421 行
></TD></TR></TABLE> </P><P>当有多个文件参数的时候, <BCLASS="COMMAND">grep</B>将会指出哪个文件中包含具体的匹配. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">grep Linux osinfo.txt misc.txt</KBD><SAMPCLASS="COMPUTEROUTPUT">osinfo.txt:This is a file containing information about Linux. osinfo.txt:The GPL governs the distribution of the Linux operating system. misc.txt:The Linux operating system is steadily gaining in popularity.</SAMP> </PRE></FONT></TD></TR></TABLE> </P><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>如果在<BCLASS="COMMAND">grep</B>命令只搜索一个文件的时候, 那么可以简单的把<TTCLASS="FILENAME">/dev/null</TT>作为第二个文件参数传递给<BCLASS="COMMAND">grep</B>. </P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">grep Linux osinfo.txt /dev/null</KBD><SAMPCLASS="COMPUTEROUTPUT">osinfo.txt:This is a file containing information about Linux. osinfo.txt:The GPL governs the distribution of the Linux operating system.</SAMP> </PRE></FONT></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><P>如果存在一个成功的匹配, 那么<BCLASS="COMMAND">grep</B>命令将会返回0作为<AHREF="exit-status.html#EXITSTATUSREF">退出状态码</A>, 这样就可以将<BCLASS="COMMAND">grep</B>命令的结果放在脚本的条件测试中来使用, 尤其和<CODECLASS="OPTION">-q</CODE>(禁止输出)选项组合时特别有用. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 SUCCESS=0 # 如果grep匹配成功 2 word=Linux 3 filename=data.file 4 5 grep -q "$word" "$filename" # "-q"选项将使得什么都不输出到stdout上. 6 7 if [ $? -eq $SUCCESS ] 8 # if grep -q "$word" "$filename" 这句话可以代替行 5 - 7. 9 then 10 echo "$word found in $filename" 11 else 12 echo "$word not found in $filename" 13 fi</PRE></FONT></TD></TR></TABLE> </P><P><AHREF="debugging.html#ONLINE">例子 29-6</A>展示了如何使用<BCLASS="COMMAND">grep</B>命令在一个系统logfile中进行一个单词的模式匹配. </P><DIVCLASS="EXAMPLE"><HR><ANAME="GRP"></A><P><B>例子 12-15. 在脚本中模拟<SPANCLASS="QUOTE">"grep"</SPAN>的行为</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # grp.sh: 一个非常粗糙的'grep'命令的实现. 3 4 E_BADARGS=65 5 6 if [ -z "$1" ] # 检查传递给脚本的参数. 7 then 8 echo "Usage: `basename $0` pattern" 9 exit $E_BADARGS 10 fi 11 12 echo 13 14 for file in * # 遍历$PWD下的所有文件. 15 do 16 output=$(sed -n /"$1"/p $file) # 命令替换. 17 18 if [ ! -z "$output" ] # 如果"$output"不加双引号将会发生什么? 19 then 20 echo -n "$file: " 21 echo $output 22 fi # sed -ne "/$1/s|^|${file}: |p" 这句与上边这段等价. 23 24 echo 25 done 26 27 echo 28 29 exit 0 30 31 # 练习: 32 # ----- 33 # 1) 在任何给定的文件中,如果有超过一个匹配的话, 在输出中添加新行. 34 # 2) 添加一些特征. </PRE></FONT></TD></TR></TABLE><HR></DIV><P>如何使用<BCLASS="COMMAND">grep</B>命令来搜索两个(或两个以上)独立的模式? 如果你想在一个或多个文件中显示既匹配<SPANCLASS="QUOTE">"pattern1"</SPAN><EM>又匹配</EM><SPANCLASS="QUOTE">"pattern2"</SPAN>的所有匹配的话, 那又该如何做呢? (译者: 这是取交集的情况, 如果取并集该怎么办呢?) </P><P>一个方法是通过<AHREF="special-chars.html#PIPEREF">管道</A>来将<BCLASS="COMMAND">grep pattern1</B>的结果传递到<BCLASS="COMMAND">grep pattern2</B>中. </P><P>比如, 给定如下文件: </P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 # 文件名: tstfile 2 3 This is a sample file. 4 This is an ordinary text file. 5 This file does not contain any unusual text. 6 This file is not unusual. 7 Here is some text.</PRE></FONT></TD></TR></TABLE> </P><P>现在, 让我们在这个文件中搜索<EM>既</EM>包含 <SPANCLASS="QUOTE">"file"</SPAN><EM>又</EM>包含<SPANCLASS="QUOTE">"text"</SPAN>的所有行. </P><TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">grep file tstfile</KBD><SAMPCLASS="COMPUTEROUTPUT"># 文件名: tstfile This is a sample file. This is an ordinary text file. This file does not contain any unusual text. This file is not unusual.</SAMP><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">grep file tstfile | grep text</KBD><SAMPCLASS="COMPUTEROUTPUT">This is an ordinary text file. This file does not contain any unusual text.</SAMP></PRE></FONT></TD></TR></TABLE><P>--</P><P><ANAME="EGREPREF"></A><BCLASS="COMMAND">egrep</B> - <EM>扩展的grep</EM> - 这个命令与<BCLASS="COMMAND">grep -E</B>等价. 这个命令用起来有些不同, 由于使用<AHREF="regexp.html#REGEXREF">正则表达式</A>的扩展集合, 将会使得搜索更具灵活性. 它也允许逻辑|(<ICLASS="FIRSTTERM">或</I>)操作. <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash $ </SAMP><KBDCLASS="USERINPUT">egrep 'matches|Matches' file.txt</KBD><SAMPCLASS="COMPUTEROUTPUT">Line 1 matches. Line 3 Matches. Line 4 contains matches, but also Matches</SAMP> </PRE></FONT></TD></TR></TABLE> </P><P><BCLASS="COMMAND">fgrep</B> - <EM>快速的grep</EM> - 这个命令与<BCLASS="COMMAND">grep -F</B>等价. 这是一种按照字符串字面意思进行的搜索(即不允许使用正则表达式), 这样有时候会使搜索变得容易一些. </P><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>在某些Linux发行版中, <BCLASS="COMMAND">egrep</B>和<BCLASS="COMMAND">fgrep</B>都是<BCLASS="COMMAND">grep</B>命令的符号链接或者别名, 只不过在调用的时候分别使用了<CODECLASS="OPTION">-E</CODE>和<CODECLASS="OPTION">-F</CODE>选项罢了. </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="DICTLOOKUP"></A><P><B>例子 12-16. 在<ICLASS="CITETITLE">1913年的韦氏词典</I>中查找定义</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # dict-lookup.sh 3 4 # 这个脚本在1913年的韦氏词典中查找定义. 5 # 这本公共词典可以通过不同的 6 #+ 站点来下载,包括 7 #+ Project Gutenberg (http://www.gutenberg.org/etext/247). 8 # 9 # 在使用本脚本之前, 10 #+ 先要将这本字典由DOS格式转换为UNIX格式(只以LF作为行结束符). 11 # 将这个文件存储为纯文本形式, 并且保证是未压缩的ASCII格式. 12 # 将DEFAULT_DICTFILE变量以path/filename形式设置好. 13 14 15 E_BADARGS=65 16 MAXCONTEXTLINES=50 # 显示的最大行数. 17 DEFAULT_DICTFILE="/usr/share/dict/webster1913-dict.txt" 18 # 默认的路径和文件名. 19 # 在必要的时候可以进行修改. 20 # 注意: 21 # ----- 22 # 这个特定的1913年版的韦氏词典 23 #+ 在每个入口都是以大写字母开头的 24 #+ (剩余的字符都是小写). 25 # 只有每部分的第一行是以这种形式开始的, 26 #+ 这也就是为什么搜索算法是下边的这个样子. 27 28 29 30 if [[ -z $(echo "$1" | sed -n '/^[A-Z]/p') ]] 31 # 必须指定一个要查找的单词, 32 #+ 并且这个单词必须以大写字母开头. 33 then 34 echo "Usage: `basename $0` Word-to-define [dictionary-file]" 35 echo 36 echo "Note: Word to look up must start with capital letter," 37 echo "with the rest of the word in lowercase." 38 echo "--------------------------------------------" 39 echo "Examples: Abandon, Dictionary, Marking, etc." 40 exit $E_BADARGS 41 fi 42 43 44 if [ -z "$2" ] # 也可以指定不同的词典 45 #+ 作为这个脚本的第2个参数传递进来. 46 then 47 dictfile=$DEFAULT_DICTFILE 48 else 49 dictfile="$2" 50 fi 51 52 # --------------------------------------------------------- 53 Definition=$(fgrep -A $MAXCONTEXTLINES "$1 \\" "$dictfile") 54 # 以 "Word \..." 这种形式定义 55 # 56 # 当然, 即使搜索一个特别大的文本文件的时候 57 #+ "fgrep"也是足够快的. 58 59 60 # 现在, 剪掉定义块. 61 62 echo "$Definition" | 63 sed -n '1,/^[A-Z]/p' | 64 # 从输出的第一行 65 #+ 打印到下一部分的第一行. 66 sed '$d' | sed '$d' 67 # 删除输出的最后两行 68 #+ (空行和下一部分的第一行). 69 # --------------------------------------------------------- 70 71 exit 0 72 73 # 练习: 74 # ----- 75 # 1) 修改这个脚本, 让它具备能够处理任何字符形式的输入 76 # + (大写, 小写, 或大小写混合), 然后将其转换为 77 # + 能够处理的统一形式. 78 # 79 # 2) 将这个脚本转化为一个GUI应用, 80 # + 使用一些比如像"gdialog"的东西 . . . 81 # 这样的话, 脚本将不再从命令行中 82 # + 取得这些参数. 83 # 84 # 3) 修改这个脚本让它具备能够分析另外一个 85 # + 公共词典的能力, 比如 U.S. Census Bureau Gazetteer.</PRE></FONT></TD></TR></TABLE><HR></DIV><P><BCLASS="COMMAND">agrep</B> (<EM>近似grep</EM>)扩展了<BCLASS="COMMAND">grep</B>近似匹配的能力. 搜索的字符串可能会与最终匹配结果所找到字符串有些不同. 这个工具并不是核心Linux发行版的一部分. </P><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>为了搜索压缩文件, 应使用<BCLASS="COMMAND">zgrep</B>, <BCLASS="COMMAND">zegrep</B>, 或<BCLASS="COMMAND">zfgrep</B>. 这些命令也可以对未压缩的文件进行搜索, 只不过会比一般的<BCLASS="COMMAND">grep</B>, <BCLASS="COMMAND">egrep</B>, 和<BCLASS="COMMAND">fgrep</B>慢上一些. 当然, 在你要搜索的文件中如果混合了压缩和未压缩的文件的话, 那么使用这些命令是非常方便的. </P><P>如果要搜索<AHREF="filearchiv.html#BZIPREF">bzipped</A>类型的文件, 使用<BCLASS="COMMAND">bzgrep</B>. </P></TD></TR></TABLE></DIV></DD><DT><BCLASS="COMMAND">look</B></DT><DD><P><BCLASS="COMMAND">look</B>命令与<BCLASS="COMMAND">grep</B>命令很相似, 但是这个命令只能做<SPANCLASS="QUOTE">"字典查询"</SPAN>, 也就是它所搜索的文件必须是已经排过序的单词列表. 默认情况下, 如果没有指定搜索哪个文件, <BCLASS="COMMAND">look</B>命令就默认搜索<TTCLASS="FILENAME">/usr/dict/words</TT>(译者: 感觉好像应该是<TTCLASS="FILENAME">/usr/share/dict/words</TT>), 当然也可以指定其他目录下的文件进行搜索. </P><DIVCLASS="EXAMPLE"><HR><ANAME="LOOKUP"></A><P><B>例子 12-17. 检查列表中单词的正确性</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?