📄 textproc.html
字号:
><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>To force <BCLASS="COMMAND">grep</B> to show the filename when searching only one target file, simply give <TTCLASS="FILENAME">/dev/null</TT> as the second file.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>grep Linux osinfo.txt /dev/null</B></TT> <TTCLASS="COMPUTEROUTPUT">osinfo.txt:This is a file containing information about Linux. osinfo.txt:The GPL governs the distribution of the Linux operating system.</TT> </PRE></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><P>If there is a successful match, <BCLASS="COMMAND">grep</B> returns an <AHREF="exit-status.html#EXITSTATUSREF">exit status</A> of 0, which makes it useful in a condition test in a script, especially in combination with the <TTCLASS="OPTION">-q</TT> option to suppress output. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 SUCCESS=0 # if grep lookup succeeds 2 word=Linux 3 filename=data.file 4 5 grep -q "$word" "$filename" # The "-q" option causes nothing to echo to stdout. 6 7 if [ $? -eq $SUCCESS ] 8 # if grep -q "$word" "$filename" can replace lines 5 - 7. 9 then 10 echo "$word found in $filename" 11 else 12 echo "$word not found in $filename" 13 fi</PRE></TD></TR></TABLE> </P><P><AHREF="debugging.html#ONLINE">Example 29-6</A> demonstrates how to use <BCLASS="COMMAND">grep</B> to search for a word pattern in a system logfile.</P><DIVCLASS="EXAMPLE"><HR><ANAME="GRP"></A><P><B>Example 12-15. Emulating <SPANCLASS="QUOTE">"grep"</SPAN> in a script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # grp.sh: Very crude reimplementation of 'grep'. 3 4 E_BADARGS=65 5 6 if [ -z "$1" ] # Check for argument to script. 7 then 8 echo "Usage: `basename $0` pattern" 9 exit $E_BADARGS 10 fi 11 12 echo 13 14 for file in * # Traverse all files in $PWD. 15 do 16 output=$(sed -n /"$1"/p $file) # Command substitution. 17 18 if [ ! -z "$output" ] # What happens if "$output" is not quoted? 19 then 20 echo -n "$file: " 21 echo $output 22 fi # sed -ne "/$1/s|^|${file}: |p" is equivalent to above. 23 24 echo 25 done 26 27 echo 28 29 exit 0 30 31 # Exercises: 32 # --------- 33 # 1) Add newlines to output, if more than one match in any given file. 34 # 2) Add features.</PRE></TD></TR></TABLE><HR></DIV><P>How can <BCLASS="COMMAND">grep</B> search for two (or more) separate patterns? What if you want <BCLASS="COMMAND">grep</B> to display all lines in a file or files that contain both <SPANCLASS="QUOTE">"pattern1"</SPAN> <ICLASS="EMPHASIS">and</I> <SPANCLASS="QUOTE">"pattern2"</SPAN>?</P><P>One method is to <AHREF="special-chars.html#PIPEREF">pipe</A> the result of <BCLASS="COMMAND">grep pattern1</B> to <BCLASS="COMMAND">grep pattern2</B>.</P><P>For example, given the following file:</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # Filename: 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></TD></TR></TABLE> </P><P>Now, let's search this file for lines containing <ICLASS="EMPHASIS">both</I> <SPANCLASS="QUOTE">"file"</SPAN> and <SPANCLASS="QUOTE">"text"</SPAN> . . . </P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>grep file tstfile</B></TT> <TTCLASS="COMPUTEROUTPUT"># Filename: 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.</TT> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>grep file tstfile | grep text</B></TT> <TTCLASS="COMPUTEROUTPUT">This is an ordinary text file. This file does not contain any unusual text.</TT></PRE></TD></TR></TABLE><P>--</P><P><ANAME="EGREPREF"></A><BCLASS="COMMAND">egrep</B> - <ICLASS="EMPHASIS">extended grep</I> - is the same as <BCLASS="COMMAND">grep -E</B>. This uses a somewhat different, extended set of <AHREF="regexp.html#REGEXREF">Regular Expressions</A>, which can make the search a bit more flexible.</P><P><BCLASS="COMMAND">fgrep</B> - <ICLASS="EMPHASIS">fast grep</I> - is the same as <BCLASS="COMMAND">grep -F</B>. It does a literal string search (no Regular Expressions), which usually speeds things up a bit.</P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>On some Linux distros, <BCLASS="COMMAND">egrep</B> and <BCLASS="COMMAND">fgrep</B> are symbolic links to, or aliases for <BCLASS="COMMAND">grep</B>, but invoked with the <TTCLASS="OPTION">-E</TT> and <TTCLASS="OPTION">-F</TT> options, respectively.</P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="DICTLOOKUP"></A><P><B>Example 12-16. Looking up definitions in <ICLASS="CITETITLE">Webster's 1913 Dictionary</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # dict-lookup.sh 3 4 # This script looks up definitions in the 1913 Webster's Dictionary. 5 # This Public Domain dictionary is available for download 6 #+ from various sites, including 7 #+ Project Gutenberg (http://www.gutenberg.org/etext/247). 8 # 9 # Convert it from DOS to UNIX format (only LF at end of line) 10 #+ before using it with this script. 11 # Store the file in plain, uncompressed ASCII. 12 # Set DEFAULT_DICTFILE variable below to path/filename. 13 14 15 E_BADARGS=65 16 MAXCONTEXTLINES=50 # Maximum number of lines to show. 17 DEFAULT_DICTFILE="/usr/share/dict/webster1913-dict.txt" 18 # Default dictionary file pathname. 19 # Change this as necessary. 20 # Note: 21 # ---- 22 # This particular edition of the 1913 Webster's 23 #+ begins each entry with an uppercase letter 24 #+ (lowercase for the remaining characters). 25 # Only the *very first line* of an entry begins this way, 26 #+ and that's why the search algorithm below works. 27 28 29 30 if [[ -z $(echo "$1" | sed -n '/^[A-Z]/p') ]] 31 # Must at least specify word to look up, and 32 #+ it must start with an uppercase letter. 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" ] # May specify different dictionary 45 #+ as an argument to this script. 46 then 47 dictfile=$DEFAULT_DICTFILE 48 else 49 dictfile="$2" 50 fi 51 52 # --------------------------------------------------------- 53 Definition=$(fgrep -A $MAXCONTEXTLINES "$1 \\" "$dictfile") 54 # Definitions in form "Word \..." 55 # 56 # And, yes, "fgrep" is fast enough 57 #+ to search even a very large text file. 58 59 60 # Now, snip out just the definition block. 61 62 echo "$Definition" | 63 sed -n '1,/^[A-Z]/p' | 64 # Print from first line of output 65 #+ to the first line of the next entry. 66 sed '$d' | sed '$d' 67 # Delete last two lines of output 68 #+ (blank line and first line of next entry). 69 # --------------------------------------------------------- 70 71 exit 0 72 73 # Exercises: 74 # --------- 75 # 1) Modify the script to accept any type of alphabetic input 76 # + (uppercase, lowercase, mixed case), and convert it 77 # + to an acceptable format for processing. 78 # 79 # 2) Convert the script to a GUI application, 80 # + using something like "gdialog" . . . 81 # The script will then no longer take its argument(s) 82 # + from the command line. 83 # 84 # 3) Modify the script to parse one of the other available 85 # + Public Domain Dictionaries, such as the U.S. Census Bureau Gazetteer.</PRE></TD></TR></TABLE><HR></DIV><P><BCLASS="COMMAND">agrep</B> (<ICLASS="EMPHASIS">approximate grep</I>) extends the capabilities of <BCLASS="COMMAND">grep</B> to approximate matching. The search string may differ by a specified number of characters from the resulting matches. This utility is not part of the core Linux distribution.</P><DIVCLASS="TIP"><TABLECLASS="TIP"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>To search compressed files, use <BCLASS="COMMAND">zgrep</B>, <BCLASS="COMMAND">zegrep</B>, or <BCLASS="COMMAND">zfgrep</B>. These also work on non-compressed files, though slower than plain <BCLASS="COMMAND">grep</B>, <BCLASS="COMMAND">egrep</B>, <BCLASS="COMMAND">fgrep</B>. They are handy for searching through a mixed set of files, some compressed, some not.</P><P>To search <AHREF="filearchiv.html#BZIPREF">bzipped</A> files, use <BCLASS="COMMAND">bzgrep</B>.</P></TD></TR></TABLE></DIV></DD><DT><BCLASS="COMMAND">look</B></DT><DD><P>The command <BCLASS="COMMAND">look</B> works like <BCLASS="COMMAND">grep</B>, but does a lookup on a <SPANCLASS="QUOTE">"dictionary"</SPAN>, a sorted word list. By default, <BCLASS="COMMAND">look</B> searches for a match in <TTCLASS="FILENAME">/usr/dict/words</TT>, but a different dictionary file may be specified.</P><DIVCLASS="EXAMPLE"><HR><ANAME="LOOKUP"></A><P><B>Example 12-17. Checking words in a list for validity</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # lookup: Does a dictionary lookup on each word in a data file. 3 4 file=words.data # Data file from which to read words to test. 5 6 echo 7 8 while [ "$word" != end ] # Last word in data file. 9 do 10 read word # From data file, because of redirection at end of loop. 11 look $word > /dev/null # Don't want to display lines in dictionary file. 12 lookup=$? # Exit status of 'look' command. 13 14 if [ "$lookup" -eq 0 ] 15 then 16 echo "\"$word\" is valid." 17 else 18 echo "\"$word\" is invalid." 19 fi 20 21 done <"$file" # Redirects stdin to $file, so "reads" come from there. 22 23 echo 24 25 exit 0 26 27 # ---------------------------------------------------------------- 28 # Code below line will not execute because of "exit" command above. 29 30 31 # Stephane Chazelas proposes the following, more concise alternative: 32 33 while read word && [[ $word != end ]] 34 do if look "$word" > /dev/null 35 then echo "\"$word\" is valid." 36 else echo "\"$word\" is invalid." 37 fi 38 done <"$file" 39 40 exit 0</PRE></TD></TR></TABLE><HR></DIV></DD><DT><BCLASS="COMMAND">sed</B>, <BCLASS="COMMAND">awk</B></DT><DD><P>Scripting languages especially suited for parsing text files and command output. May be embedded singly or in combination in pipes and shell scripts.</P></DD><DT><BCLASS="COMMAND"><AHREF="sedawk.html#SEDREF">sed</A></B></DT><DD><P>Non-interactive <SPANCLASS="QUOTE">"stream editor"</SPAN>, permits using many <BCLASS="COMMAND">ex</B> commands in batch mode. It finds many uses in shell scripts.</P></DD><DT><BCLASS="COMMAND"><AHREF="awk.html#AWKREF">awk</A></B></DT><DD><P>Programmable file extractor and formatter, good for manipulating and/or extracting fields (columns) in structured text files. Its syntax is similar to C.</P></DD><DT><BCLASS="COMMAND">wc</B></DT><DD><P><ICLASS="EMPHASIS">wc</I> gives a <SPANCLASS="QUOTE">"word count"</SPAN> on a file or I/O stream: <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash $ </TT><TTCLASS="USERINPUT"><B>wc /usr/share/doc/sed-4.1.2/README</B></TT> <TTCLASS="COMPUTEROUTPUT"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -