LINUX sed grep awk之间比较整理

来源:互联网 发布:校园网络组建方案 编辑:程序博客网 时间:2024/06/04 18:59

linux grep命令


Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。

linuxsed命令

sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

linuxawk命令

史上最好用的翻墙利器

简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

awk3个不同版本: awknawkgawk,未作特别说明,一般指gawkgawkAWKGNU版本。

awk其名称得自于它的创始人Alfred AhoPeter WeinbergerBrian Kernighan姓氏的首个字母。实际上AWK的确拥有自己的语言:AWK程序设计语言 , 三位创建者已将它正式定义为样式扫描和处理语言。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

 

正则表达式基础

在最简单的情况下,一个正则表达式看上去就是一个普通的查找串。例如,正则表达式"testing"中没有包含任何元字符,,它可以匹配"testing""123testing"等字符串,但是不能匹配"Testing"

要想真正的用好正则表达式,正确的理解元字符是最重要的事情。下表列出了所有的元字符和对它们的一个简短的描述。

元字符

 

描述

 

 

 

.

 

匹配任何单个字符。例如正则表达式r.t匹配这些字符串:ratrutr t,但是不匹配root 

$

 

匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels." 

^

 

匹配一行的开始。例如正则表达式^When in能够匹配字符串"When in the course of human events"的开始,但是不能匹配"What and When in the"

*

 

匹配0或多个正好在它之前的那个字符。例如正则表达式.*意味着能够匹配任意数量的任何字符。

\

 

这是引用府,用来将这里列出的这些元字符当作普通的字符来进行匹配。例如正则表达式\$被用来匹配美元符号,而不是行尾,类似的,正则表达式\.用来匹配点字符,而不是任何字符的通配符。

[ ] 
[c1-c2]
[^c1-c2]

 

匹配括号中的任何一个字符。例如正则表达式r[aou]t匹配ratrotrut,但是不匹配ret。可以在括号中使用连字符-来指定字符的区间,例如正则表达式[0-9]可以匹配任何数字字符;还可以制定多个区间,例如正则表达式[A-Za-z]可以匹配任何大小写字母。另一个重要的用法是排除,要想匹配除了指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符,例如正则表达式[^269A-Z] 将匹配除了269和所有大写字母之外的任何字符。

\< \>

 

匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\<the能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"注意:这个元字符不是所有的软件都支持的。

 

 

  之间的表达式定义为group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用\1 \9 的符号来引用。

|

 

将两个匹配条件进行逻辑Or)运算。例如正则表达式(him|her) 匹配"it belongs to him""it belongs to her",但是不能匹配"it belongs to them."注意:这个元字符不是所有的软件都支持的。

+

 

匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配999999等。注意:这个元字符不是所有的软件都支持的。

?

 

匹配01个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。

\{i\}
\{i,j\}

 

匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]\{3\} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123A348等,但是不匹配A1234。而正则表达式[0-9]\{4,6\} 匹配连续的任意4个、5个或者6个数字字符。注意:这个元字符不是所有的软件都支持的。

 

正则表达式语法支持情况

命令或环境

.

[ ]

^

$

 

\{ \}

?

+

|

( )

vi

 X 

 X 

 X 

 X 

 X 

 

 

 

 

 

Visual C++

 X 

 X 

 X 

 X 

 X 

 

 

 

 

 

awk

 X 

 X 

 X 

 X 

 

 

 X 

 X 

 X 

 X 

sed

 X 

 X 

 X 

 X 

 X 

 X 

 

 

 

 

Tcl

 X 

 X 

 X 

 X 

 X 

 

 X 

 X 

 X 

 X 

ex

 X 

 X 

 X 

 X 

 X 

 X 

 

 

 

 

grep

 X 

 X 

 X 

 X 

 X 

 X 

 

 

 

 

egrep

 X 

 X

 X 

 X 

 X 

 

 X 

 X 

 X 

 X 

fgrep

 X 

 X 

 X 

 X 

 X 

 

 

 

 

 

perl

 X

 X

 X

 X

 X

 

 X

 X

 X

 X

 

 

 

awk是不支持 \{\}sed可以

 

以下是测试:

 

代码如下:


# vi regular_express.txt
-------------------------------
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $ 3183 dollars.
GNU is free air not free beer.
Her hair is very beauty.
I can't finish the test.
Oh! The soup taste good.
motorcycle is cheap than car.
This window is clear.
the symbol '*' is represented as start.
Oh!My god!
The gd software is a library for drafting programs.
You are the best is mean you are the no. 1.
The world <Happy> is the same with "glad".
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let's go.
# I am VBird
--------------------------------

 

grep

1.搜寻特定字符串"the"
注: n为显示行号

代码如下:

#grep -n 'the' regular_express.txt

2.反向搜寻特定字符串"the"

代码如下:

#grep -vn 'the' regular_express.txt

3.取得任意大小写"the"的这个字符串

代码如下:

#grep -in 'the' regular_express.txt

4.利用括号 [] 来搜寻集合字符
搜索test或tast这两个单词时,发现他们有共同的't?st',所以可以这么搜寻

复制代码代码如下:

#grep -n 't[ae]st' regular_express.txt


这样其实就是在找t[a]st和t[e]st这两个分开的字符
如果搜索有 oo 的字符时,则可以使用:

代码如下:

# grep -n 'oo' regular_express.txt


如果搜索oo时不想搜到 oo 前面有 g 的话,我们可以利用反向选择[^]来达成:

代码如下:

# grep -n '[^g]oo'  regular_express.txt


如果搜索oo前面不想有小写字符,则:

代码如下:

# grep -n '[^a-z]oo' regular_express.txt


注: 大写英文/小写英文/数字 可以使用 [a-z]/[A-Z]/[0-9]等方式来书写,也可以写在一起
[a-zA-Z0-9]表示要求字符串是数字以及英文
如果我们要取得有数字的那行,则:

代码如下:

# grep -n '[0-9]' regular_express.txt


注:但考虑到语系对编码顺序的影响,因此除了连续编码使用减号[-]外,也可以用[:lower:]代替a-z 以及 [:digit:] 代替0-9 使用

代码如下:

# grep -n '[^[:lower:]]oo' regular_express.txt
# grep -n '[[:digit:]]' regular_express.txt

5.显示行首为'the'的字符串

代码如下:

# grep -n '^the' regular_express.txt


显示行首是小写字符

代码如下:

# grep -n '^[a-z]' regular_express.txt

6.显示行尾为点 . 的那一行

代码如下:

# grep -n '\.$' regular_express.txt

7.显示5-9行数据

代码如下:

# cat -An regular_express.txt |head -n 10 |tail -n 6

8.显示空白行

代码如下:

# grep -n '^$' regular_express.txt

9.找出g??d字符串,起头g结束d的四个字符串

代码如下:

# grep -n 'g..d' regular_express.txt

10. o*代表空字符(就是有没有字符都可以)或者一个到N个o字符,所以grep -n 'o*' regular_express.txt就会把所有行全部打印出来,
11.oo*代表o+空字符或者一个到N个o字符,所以grep -n 'oo*' regular_express.txt就会把o,oo,ooo等的行全部打印出来
12."goo*g"代表gog,goog,gooog...等

代码如下:

# grep -n 'goo*g' regular_express.txt

13.找出含g...g字符串的行
注: .代表任意字符, .*则就代表空字符或者一个到N个任意字符

代码如下:

# grep -n 'g.*g' regular_express.txt

14.找出含有数字的行

代码如下:

# grep -n '[0-9][0-9]*' regular_express.txt


或# grep -n '[0-9]' regular_express.txt

15.找出含两个o的字符串
注:{}因为在shell里有特殊意义,所以需要加跳脱符\来让其失去意义

代码如下:

# grep -n 'o\{2\}'  regular_express.txt


找出g后含2到5个o然后以g结尾的字符串

代码如下:

# grep -n 'go\{2,5\}g'  regular_express.txt


找出g后含2以上的o然后以g结尾的字符串

代码如下:

# grep -n 'go\{2,\}g'  regular_express.txt


总结:
^word     表示带搜寻的字符串(word)在行首
word$     表示带搜寻的字符串(word)在行尾
.         表示1个任意字符
\         表示转义字符,在特殊字符前加\会将原本的特殊字符意义去除
*         表示重复0到无穷多个前一个RE(正则表达式)字符
[list]    表示搜索含有list的字符串
[n1-n2]   表示搜索指定的字符串范围,例如[0-9] [a-z] [A-Z]等
[^list]   表示反向字符串的范围,例如[0-9]表示非数字字符,[A-Z]表示非大写字符范围
\{n,m\}   表示找出n到m个前一个RE字符
\{n,\}    表示n个以上的前一个RE字符
egrep总结:
+    表示重复一个或一个以上的前一个RE字符
范例:egrep 'go+d' regular_express.txt
表示搜寻(god)(good)(goood)...等等字符串,o+代表[一个以上的o]
?    表示重复零个或一个的前一个RE字符
范例:egrep 'go?d' regular_express.txt
表示搜寻(gd)(god)字符串,o?代表[空的或1个o]
注:egrep下'go+d'和'go?d'的结果集合就等于grep下的'go*d'
|    表示用或(or)的方式找出数个字符串
范例:egrep 'gd|good|dog' regular_express.txt
表示搜寻(gd)或(god)或(god)字符串,|代表或
()    表示找出群组字符串
范例:egrep 'g(la|oo)d' regular_express.txt
表示搜寻(glad)或(good)字符串
()    +表示找出多个重复群组的判别
范例: echo 'AxyzxyzxyzxyzxyzC'|egrep 'A(xyz)+C'
表示搜寻开头是A结尾是C,中间有一个以上的'xyz'字符串

 

sed:

插入:

1.将/etc/passwd 的内容列出并打印行号,同时,将2-5行删除显示

代码如下:

#nl /etc/passwd | sed '2,5d'


注: sed是sed -e的简写, 后接单引号
同上删除第2行

代码如下:

# nl /etc/passwd | sed '2d'


同上删除第三行到最后一行

代码如下:

# nl /etc/passwd | sed '3,$d'

2.在第二行后加上一行test

代码如下:

# nl /etc/passwd | sed '2a test'


在第二行前加上一行test

代码如下:

# nl /etc/passwd | sed '2i test'


在第二行后加入两行test

代码如下:

# nl /etc/passwd | sed '2a test \
> test'

替换行:

3.将2-5行内容取代为 No 2-5 number

代码如下:

# nl /etc/passwd | sed '2,5c No 2-5 number'

4 列出/etc/passwd 内第5-7行

代码如下:

# nl /etc/passwd |sed -n '5,7p'

替换字符串:

sed 's/被替换字符串/新字符串/g'

1.获取本机IP的行

代码如下:

# /sbin/ifconfig eth0 |grep 'inet addr'


将IP前面的部分予以删除

代码如下:

# /sbin/ifconfig eth0 |grep 'inet addr'| sed 's/^.*addr://g'


将IP后面的部分删除

代码如下:

# /sbin/ifconfig eth0 |grep 'inet addr'| sed 's/^.*addr://g'| sed 's/Bcast:.*$//g'
-------------------
192.168.100.74
-------------------

2.用grep将关键词MAN所在行取出来

代码如下:

# cat /etc/man.config |grep 'MAN'


删除批注行

代码如下:

# cat /etc/man.config |grep 'MAN'| sed 's/^#.*$//g'


删除空白行

代码如下:

# cat /etc/man.config |grep 'MAN'| sed 's/^#.*$//g'| sed '/^$/d'

3.利用sed将regular_express.txt内每一行若为.的换成!
注:-i参数会直接修改文本,而并非直接输出

代码如下:

# sed -i 's/.*\.$/\!/g' regular_express.txt

4.利用sed在文本最后一行加入 #This is a test
注: $代表最后一行 a代表行后添加

代码如下:

# sed -i '$a #This is a test' regular_express.txt


将selinux配置文件enforcing改成disabled

复制代码

# sed -i '6,6c SELINUX=disabled' /etc/selinux/config


延伸正规表示法:

代码如下:

# grep -v '^$' regular_express.txt |grep -v '^#'


延伸写法:

代码如下:

# egrep -v '^$'|'^#' regular_express.txt

1. +表示重复一个或一个以上的前一个RE字符

例如:egrep -n 'go+d' regular_express.txt
普通写法: grep -n 'goo*d' regular_express.txt

2. ?表示重复零个或一个前一个RE字符

例如: egrep -n 'go?d' regular_express.txt

3. |表示用或的方式找出数个字符串

例如: egrep -n 'gd|good' regular_express.txt

4. ()表示找出群组字符串

例如: egrep -n 'g(la|oo)d' regular_express.txt
也就是搜寻(glad)或good这两个字符串

5. ()+多个重复群组判别

例如: echo 'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C'

也就是要找开头是A结尾是C 中间有一个以上的'xyz'字符串的意思

awk:

一行一行的分析处理awk '条件类型1{动作1}条件类型2{动作2}' filename, awk 也可以读取来自前一个指令的 standard input
相对于sed常常用于一整行处理, awk则比较倾向于一行当中分成数个"字段"(区域)来处理,默认的分隔符是空格键或tab


例如:
last -n 5 | awk '{print $1 "\t" $3}'这里大括号内$1"\t"$3之间不加空格也可以,不过最好还是加上个空格,另外注意"\t"是有双引号的,因为本身这些内容都在单引号内
$0 代表整行 $1代表第一个区域,依此类推


awk的处理流程是:
1. 读第一行, 将第一行资料填入变量$0, $1...等变量中
2. 依据条件限制, 执行动作
3. 接下来执行下一行


所以, AWK一次处理是一行,而一次中处理的最小单位是一个区域
另外还有3个变量, NF:每一行处理的字段数, NR目前处理到第几行 FS目前的分隔符
逻辑判断 > < >= <= == !== , 赋值直接使用=
cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t" $3}'首先定义分隔符为:,然后判断,注意看,判断没有写在{},然后执行动作, FS=":"这是一个动作,赋值动作,不是一个判断,所以不写在{}
BEGIN END , 给程序员一个初始化和收尾的工作, BEGIN之后列出的操作在{}内将在awk开始扫描输入之前执行,END{}内的操作,将在扫描完输入文件后执行.
awk '/test/ {print NR}' abc将带有test的行的行号打印出来,注意//之间可以使用正则表达式
awk {},可以使用if else ,for(i=0;i<10;i++), i=1 while(i<NF)
可见awk的很多用法都等同于C语言,比如"\t"分隔符, print的格式, if, while, for等等

awk是相当复杂的工具,真正使用时,再补充吧. (有关工具的picture)

0 0