grep awk和sed命令详解

》grep help摘要

用法: grep [选项]... PATTERN [FILE]...
在每个 FILE 或是标准输入中查找 PATTERN。
默认的 PATTERN 是一个基本正则表达式(缩写为 BRE)。
例如: grep -i 'hello world' menu.h main.c

正则表达式选择与解释:
  -E, --extended-regexp     PATTERN 是一个可扩展的正则表达式(缩写为 ERE)
  -F, --fixed-strings       PATTERN 是一组由断行符分隔的字符串。
  -G, --basic-regexp        PATTERN 是一个基本正则表达式(缩写为 BRE)
  -P, --perl-regexp         PATTERN 是一个 Perl 正则表达式
  -e, --regexp=PATTERN      用 PATTERN 来进行匹配操作
  -f, --file=FILE           从 FILE 中取得 PATTERN
  -i, --ignore-case         忽略大小写
  -w, --word-regexp         强制 PATTERN 仅完全匹配字词
  -x, --line-regexp         强制 PATTERN 仅完全匹配一行
  -z, --null-data           一个 0 字节的数据行,但不是空行


杂项:
  -s, --no-messages         不显示错误信息
  -v, --invert-match        选中不匹配的行
  -V, --version             显示版本信息并退出
      --help                显示此帮助并退出


输出控制:
  -m, --max-count=NUM       NUM 次匹配后停止
  -b, --byte-offset         输出的同时打印字节偏移
  -n, --line-number         输出的同时打印行号
      --line-buffered       每行输出清空
  -H, --with-filename       为每一匹配项打印文件名
  -h, --no-filename         输出时不显示文件名前缀
      --label=LABEL         将LABEL 作为标准输入文件名前缀
  -o, --only-matching       只显示匹配PATTERN 部分的行
  -q, --quiet, --silent     不显示所有常规输出
      --binary-files=TYPE   设定二进制文件的TYPE 类型;
                            TYPE 可以是`binary', `text', 或`without-match'
  -a, --text                等同于 --binary-files=text
  -I                        等同于 --binary-files=without-match
  -d, --directories=ACTION  读取目录的方式;
                            ACTION 可以是`read', `recurse',或`skip'
  -D, --devices=ACTION      读取设备、先入先出队列、套接字的方式;
                            ACTION 可以是`read'或`skip'
  -r, --recursive           等同于--directories=recurse
  -R, --dereference-recursive       同上,但遍历所有符号链接
      --include=FILE_PATTERN  只查找匹配FILE_PATTERN 的文件
      --exclude=FILE_PATTERN  跳过匹配FILE_PATTERN 的文件和目录
      --exclude-from=FILE   跳过所有除FILE 以外的文件
      --exclude-dir=PATTERN  跳过所有匹配PATTERN 的目录。
  -L, --files-without-match  只打印不匹配FILEs 的文件名
  -l, --files-with-matches  只打印匹配FILES 的文件名
  -c, --count               只打印每个FILE 中的匹配行数目
  -T, --initial-tab         行首tabs 分隔(如有必要)
  -Z, --null                在FILE 文件最后打印空字符


文件控制:
  -B, --before-context=NUM  打印文本及其前面NUM 行
  -A, --after-context=NUM   打印文本及其后面NUM 行
  -C, --context=NUM         打印NUM 行输出文本
  -NUM                      等同于 --context=NUM
      --color[=WHEN],
      --colour[=WHEN]       使用标记高亮匹配字串;
                            WHEN 可以是`always', `never'或`auto'
  -U, --binary              不要清除行尾的CR 字符(MSDOS/Windows)
  -u, --unix-byte-offsets   忽略CR 字符,报告字节偏移
    (MSDOS/Windows)


'egrep' 即'grep -E'。'fgrep' 即'grep -F'。
直接调用'egrep' 或是'fgrep' 均已被废弃。
若FILE 为 -,将读取标准输入。不带FILE,读取当前目录,除非命令行中指定了-r 选项。
如果少于两个FILE 参数,就要默认使用-h 参数。
如果有任意行被匹配,那退出状态为 0,否则为 1;
如果有错误产生,且未指定 -q 参数,那退出状态为 2


1、awk命令

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,把文件逐行的读入以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk命令形式:
awk [-F|-f|-v]  'commands' input-file(s)
 [-F|-f|-v] -F指定分隔符,-f调用脚本,-v定义变量 var=value
'commands  '      可以是引用代码块 'BEGIN{}  {command1; command2} END{}'
BEGIN   初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,命令代码块可包含一条或多条命令
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
如果只需要文本中某列信息,或某几列信息
[plain]  view plain  copy
  1. example.txt   
  2. name english Totalscore  
  3. jason  90     100  
  4. json   80     101  
  5. Mirro  78     102  
  6. cat example.txt | awk '{print $1,$3}'  
执行结果:


awk命令执行时,会先读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域, $0则表示所有域,$1表示第一个域,$n表示第n个域。 默认域分隔符是"空白键" 或 "[tab]键",上面没有使用"-F"指定分隔符,下面命令指定分隔符为":",显示/etc/passwd的第一列,即账户
[plain]  view plain  copy
  1. cat /etc/passwd |awk  -F ':'  '{print $1}'    
  2. #显示分隔后的第一列和第三列,以tab键分隔  
  3. cat /etc/passwd |awk  -F ':'  '{print $1"\t"$3}'    
  4. #搜索example.txt有jason关键字的所有行   
  5. awk '/jason/' example.txt     
  6. #搜索example.txt有jason关键字的所有行,并显示第三列  
  7. awk '/jason/{print $3}' example.txt            
  8. #搜索支持正则,例如找jason开头的:  
  9. awk -F: '/^jason/' example.txt   
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在第一行添加列名name,shell,在最后一行添加"end"。
[plain]  view plain  copy
  1. cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "end"}'  
  2. awk  -F ':'   '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' example.txt   

上面awk命令是先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,随后开始执行模式所对应的动作action。再读入第二条记录,直到所有的记录读完,最后执行END操作。
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量

[plain]  view plain  copy
  1. ARGC               命令行参数个数  
  2. ARGV               命令行参数排列  
  3. ENVIRON            支持队列中系统环境变量的使用  
  4. FILENAME           awk浏览的文件名  
  5. FNR                浏览文件的记录数  
  6. FS                 设置输入域分隔符,等价于命令行 -F选项  
  7. NF                 浏览记录的域的个数  
  8. NR                 已读的记录数  
  9. OFS                输出域分隔符  
  10. ORS                输出记录分隔符  
  11. RS                 控制记录分隔符  
上面的命令统计example.txt 文件名,每行的行号,每行的列数,对应的完整行内容, 利用printf替代print,可以让代码更加简洁,易读,如下:
[plain]  view plain  copy
  1. awk  -F ':'  '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' example.txt  

awk中同时提供了print和printf两种打印输出的函数,其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。printf函数,其用法和C语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

awk还可以自定义变量

[plain]  view plain  copy
  1. awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd  
count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。 这里没有初始化count,虽然默认,也可以初始化count:
[plain]  view plain  copy
  1. awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd  
  2. #统计某个文件夹下的文件占用的字节数  
  3. ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'    
  4. #统计某个文件夹下的文件(不含子目录)占用的字节数,以M为单位显示  
  5. ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'   
  6. #awk中使用for循环遍历数组  
  7. awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd   

awk的用法极多,更多请参考 http://www.gnu.org/software/gawk/manual/gawk.html

2、sed命令

sed是一种流编辑器,在文本处理中非常适用的工具,能够配合正则表达式使用。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。

sed命令格式

[plain]  view plain  copy
  1. sed [options] 'command' file(s)   
  2. sed [options] -f scriptfile file(s)  
常用选项:
        -n∶sed 的用法中,所有来自 STDIN的资料都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 

常用命令:
        a   ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
        c   ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
        d   ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
         i   ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
         p  ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
         s  ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

删除某行:

[plain]  view plain  copy
  1. sed '1d' example.txt        #删除第一行   
  2. sed '$d' example.txt              #删除最后一行  
  3. sed '1,2d' example.txt          #删除第一行到第二行  
  4. sed '2,$d' example.txt          #删除第二行到最后一行  
显示某行:

[plain]  view plain  copy
  1. sed -n '1p' example.txt           #显示第一行   
  2. sed -n '$p' example.txt           #显示最后一行  
  3. sed -n '1,2p' example.txt        #显示第一行到第二行  
  4. sed -n '2,$p' example.txt        #显示第二行到最后一行  
模式进行查询:
[plain]  view plain  copy
  1. sed -n '/ruby/p' example.txt    #查询包括关键字ruby所在所有行  
  2. sed -n '/\$/p' example.txt        #查询包括关键字$所在所有行,使用反斜线\屏蔽特殊含义  
替换一行中的某部分:
[plain]  view plain  copy
  1. #格式:sed 's/要替换的字符串/新的字符串/'   (要替换的字符串可以用正则表达式)  
  2. sed -n '/jason/p' example.txt | sed 's/jason/bird/'    #替换jason为bird  
  3. sed -n '/jason/p' example.txt | sed 's/jason//g'        #删除jason,h后面添加g表示全部替换  
sed替换标记:

命令 说明
g 表示行内全面替换
p 表示打印行
w 表示把行写入一个文件
x 表示互换模板块中的文本和缓冲区中的文本
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
\1 子串匹配标记
& 已匹配字符串标记
删除匹配行:

[plain]  view plain  copy
  1. sed '/^$/d' test.txt #删除空白行  
  2. sed '/^aa/'d test.txt # 删除文件中所有以aa开头的行,sed -i '/匹配字符串/d'  file   
[plain]  view plain  copy
  1. #从第N处匹配开始替换时,可以使用 /Ng  
  2. sed 's/book/books/g' file #使用后缀 /g 标记会替换每一行中的所有匹配  
  3. echo this is digit 7 in a number | sed 's/digit [0-9]/\1/'  
命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,.. 用于匹配子串,对于匹配到的第一个子串就标记为 \1,依此类推匹配到的第二个结果就是 \2

组合多个表达式 
sed '表达式' | sed '表达式' <==> sed '表达式; 表达式'
sed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号。

[plain]  view plain  copy
  1. test=hello   
  2. echo hello WORLD | sed "s/$test/HELLO"   
  3. HELLO WORLD  
这两个命令用法都很多,没有一一列举,只是列举了下自己用得比较多的,有兴趣的可以自己去再收集下。

参考文档:

http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

http://man.linuxde.NET/sed

http://www.cnblogs.com/maxincai/p/5146338.html

你可能感兴趣的:(linux,文本)