grep命令学习

  • grep

1.命令格式:

grep [option] pattern file

2.命令功能:

用于过滤/搜索的特定字符。可使用正则表达式能多种命令配合使用,使用上十分灵活

3.命令参数:

-a   --text   #不要忽略二进制的数据。   

-A<显示行数>   --after-context=<显示行数>   #除了显示符合范本样式的那一列之外,并显示该行之后的内容。   

-b   --byte-offset   #在显示符合样式的那一行之前,标示出该行第一个字符的编号。   

-B<显示行数>   --before-context=<显示行数>   #除了显示符合样式的那一行之外,并显示该行之前的内容。   

-c    --count   #计算符合样式的列数。   

-C<显示行数>    --context=<显示行数>或-<显示行数>   #除了显示符合样式的那一行之外,并显示该行之前后的内容。   

-d <动作>      --directories=<动作>   #当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。   

-e<范本样式>  --regexp=<范本样式>   #指定字符串做为查找文件内容的样式。   

-E      --extended-regexp   #将样式为延伸的普通表示法来使用。   

-f<规则文件>  --file=<规则文件>   #指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。   

-F   --fixed-regexp   #将样式视为固定字符串的列表。   

-G   --basic-regexp   #将样式视为普通的表示法来使用。   

-h   --no-filename   #在显示符合样式的那一行之前,不标示该行所属的文件名称。   

-H   --with-filename   #在显示符合样式的那一行之前,表示该行所属的文件名称。   

-i    --ignore-case   #忽略字符大小写的差别。   

-l    --file-with-matches   #列出文件内容符合指定的样式的文件名称。   

-L   --files-without-match   #列出文件内容不符合指定的样式的文件名称。   

-n   --line-number   #在显示符合样式的那一行之前,标示出该行的列数编号。   

-q   --quiet或--silent   #不显示任何信息。   

-r   --recursive   #此参数的效果和指定“-d recurse”参数相同。   

-s   --no-messages   #不显示错误信息。   

-v   --revert-match   #显示不包含匹配文本的所有行。   

-V   --version   #显示版本信息。   

-w   --word-regexp   #只显示全字符合的列。   

-x    --line-regexp   #只显示全列符合的列。   

-y   #此参数的效果和指定“-i”参数相同。

  

4.规则表达式:

grep的规则表达式:

^  #锚定行的开始 如:'^grep'匹配所有以grep开头的行。    

$  #锚定行的结束 如:'grep$'匹配所有以grep结尾的行。    

.  #匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。    

*  #匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。    

.*   #一起用代表任意字符。   

[]   #匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。    

[^]  #匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。    

\(..\)  #标记匹配字符,如'\(love\)',love被标记为1。    

\<      #锚定单词的开始,如:'\<grep'匹配包含以grep开头的单词的行。    

\>      #锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。    

x\{m\}  #重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。    

x\{m,\}  #重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。    

x\{m,n\}  #重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。   

\w    #匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。   

\W    #\w的反置形式,匹配一个或多个非单词字符,如点号句号等。   

\b    #单词锁定符,如: '\bgrep\b'只匹配grep。  


POSIX字符:

为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating System Interface)增加了特殊的字符类,如[:alnum:]是[A-Za-z0-9]的另一个写法。要把它们放到[]号内才能成为正则表达式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。


[:alnum:]    #文字数字字符   

[:alpha:]    #文字字符   

[:digit:]    #数字字符   

[:graph:]    #非空字符(非空格、控制字符)   

[:lower:]    #小写字符   

[:cntrl:]    #控制字符   

[:print:]    #非空字符(包括空格)   

[:punct:]    #标点符号   

[:space:]    #所有空白字符(新行,空格,制表符)   

[:upper:]    #大写字符   

[:xdigit:]   #十六进制数字(0-9,a-f,A-F)  


  • 使用正则表达式的一个多用途文本搜索工具. 这个命令本来是ed行编辑器中的一个命令/过滤器: g/re/p -- global - regular expression - print.


    grep pattern [file...]

    在文件中搜索所有pattern出现的位置, pattern既可以是要搜索的字符串, 也可以是一个正则表达式.



    bash$ grep '[rst]ystem.$' osinfo.txt
    The GPL governs the distribution of ... Linux operating system.


    如果没有指定文件参数, grep通常用在管道中对stdout进行过滤.


    bash$ ps ax | grep clock
    765 tty1     S      0:00 xclock
    901 pts/1    S      0:00 grep clock	


    -i 选项在搜索时忽略大小写.

    -w 选项用来匹配整个单词.

    -l 选项仅列出符合匹配的文件, 而不列出匹配行.

    -r (递归) 选项不仅在当前工作目录下搜索匹配, 而且搜索子目录.

    -n 选项列出所有匹配行, 并显示行号.


    bash$ grep -n Linux osinfo.txt
    2:This is a file containing information about Linux.
    6:The GPL governs the distribution of the Linux operating system.	


    -v (或者--invert-match)选项将会显示所有不匹配的行.

      1 grep pattern1 *.txt | grep -v pattern2
      2 
      3 # 匹配在"*.txt"中所有包含 "pattern1"的行, 
      4 # 而***不显示***匹配包含"pattern2"的行.	


    -c (--count) 选项将只会显示匹配到的行数的总数,而不会列出具体的匹配.

      1 grep -c txt *.sgml   # (在 "*.sgml" 文件中, 匹配"txt"的行数的总数.)
      2 
      3 
      4 #   grep -cz .
      5 #            ^ 点
      6 # 意思是计数 (-c) 所有以空字符分割(-z) 的匹配 "."的项
      7 # "."是正则表达式的一个符号, 表达匹配任意一个非空字符(至少要包含一个字符).
      8 # 
      9 printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz .     # 3
     10 printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '$'   # 5
     11 printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -cz '^'   # 5
     12 #
     13 printf 'a b\nc  d\n\n\n\n\n\000\n\000e\000\000\nf' | grep -c '$'    # 9
     14 # 默认情况下, 是使用换行符(\n)来分隔匹配项.
     15 
     16 # 注意  -z 选项是 GNU "grep" 特定的选项.
     17 
     18 
     19 # 感谢, S.C.


    当有多个文件参数的时候, grep将会指出哪个文件中包含具体的匹配.


    bash$ grep Linux osinfo.txt misc.txt
    osinfo.txt:The GPL governs the distribution of the Linux...
    misc.txt:The Linux operating system is steadily ...	



    grep命令学习

    如果在grep命令只搜索一个文件的时候, 那么可以简单的把/dev/null作为第二个文件参数传递给grep.


    bash$ grep Linux osinfo.txt /dev/nullosinfo.txt:This is a file containing information about Linux. osinfo.txt:The GPL governs the distribution of the Linux operating system.      


    如果存在一个成功的匹配, 那么grep命令将会返回0作为退出状态码, 这样就可以将grep命令的结果放在脚本的条件测试中来使用, 尤其和-q(禁止输出)选项组合时特别有用.

      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


    例子 29-6展示了如何使用grep命令在一个系统logfile中进行一个单词的模式匹配.



    例子 12-15. 在脚本中模拟"grep"的行为

      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) 添加一些特征.

    如何使用grep命令来搜索两个(或两个以上)独立的模式? 如果你想在一个或多个文件中显示既匹配"pattern1"又匹配"pattern2"的所有匹配的话, 那又该如何做呢? (译者: 这是取交集的情况, 如果取并集该怎么办呢?)

    一个方法是通过管道来将grep pattern1的结果传递到grep pattern2中.

    比如, 给定如下文件:


      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.


    现在, 让我们在这个文件中搜索包含 "file"包含"text"的所有行.

    bash$ grep file tstfile# 文件名: 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.bash$ grep file tstfile | grep textThis is an ordinary ...
     This file does not contain any unusual text.


  • egrep - 扩展的grep - 这个命令与grep -E等价. 这个命令用起来有些不同, 由于使用正则表达式的扩展集合, 将会使得搜索更具灵活性. 它也允许逻辑|()操作.

    bash $ egrep 'matches|Matches' file.txtLine 1 matches.
     Line 3 Matches.
     Line 4 contains matches, but also Matches


    fgrep - 快速的grep - 这个命令与grep -F等价. 这是一种按照字符串字面意思进行的搜索(即不允许使用正则表达式), 这样有时候会使搜索变得容易一些.


    grep命令学习

    在某些Linux发行版中, egrepfgrep都是grep命令的符号链接或者别名, 只不过在调用的时候分别使用了-E-F选项罢了.



    例子 12-16. 在1913年的韦氏词典中查找定义

      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.

    agrep (近似grep)扩展了grep近似匹配的能力. 搜索的字符串可能会与最终匹配结果所找到字符串有些不同. 这个工具并不是核心Linux发行版的一部分.


    grep命令学习

    为了搜索压缩文件, 应使用zgrepzegrep, 或zfgrep. 这些命令也可以对未压缩的文件进行搜索, 只不过会比一般的grepegrep, 和fgrep慢上一些. 当然, 在你要搜索的文件中如果混合了压缩和未压缩的文件的话, 那么使用这些命令是非常方便的.

    如果要搜索bzipped类型的文件, 使用bzgrep.


--摘自ABS


补充:

2017.05.11

 Linux系统下比较两个文件并删除相同部分

   方法一:

  comm -23 file1 file2

  方法二:

  grep -v -f file1 file2

  /*注::此法在对比数字时候比较凑效果,文本对比不建议使用*/

  方法三:

  awk '{print NR,$0}' file1 file2 |sort -k2|uniq -u -f 1|sort -k1|awk '{print $2}'

  或者:

  awk '{print $0}' file1 file2 |sort|uniq -u

1、统计两个文本文件的相同行

grep -Ff file1 file2

2、统计file1中有,file2中没有的行

grep -vFf file1 file2

grep -Fvxf <(grep -Fxf file1 file2 ) file1 file2

如何比较两个文件并去删除相同的内容

for i in $(<file1); do grep $i file2 || echo $i >>tmp1 ; done

输出相同行:

$grep -wf file1 file2

输出不同行

 $grep -wvf file1 file2



anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/2064.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注