您的位置:首页 > 运维架构 > Linux

LINUX sed grep awk之间比较整理

2016-07-16 10:17 405 查看
linux grep命令

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

linuxsed命令

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

linuxawk命令

史上最好用的翻墙利器

简介

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk是
AWK的
GNU版本。
awk其名称得自于它的创始人Alfred Aho
、Peter Weinberger和
Brian Kernighan姓氏的首个字母。实际上
AWK的确拥有自己的语言:
AWK程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。
 

正则表达式基础

在最简单的情况下,一个正则表达式看上去就是一个普通的查找串。例如,正则表达式"testing"中没有包含任何元字符,,它可以匹配"testing"和"123testing"等字符串,但是不能匹配"Testing"。
要想真正的用好正则表达式,正确的理解元字符是最重要的事情。下表列出了所有的元字符和对它们的一个简短的描述。
元字符
 

描述
 

 

 

.
 

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

$
 

匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"<
4000
/span>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匹配rat、rot和rut,但是不匹配ret。可以在括号中使用连字符-来指定字符的区间,例如正则表达式[0-9]可以匹配任何数字字符;还可以制定多个区间,例如正则表达式[A-Za-z]可以匹配任何大小写字母。另一个重要的用法是“排除”,要想匹配除了指定区间之外的字符——也就是所谓的补集——在左边的括号和第一个字符之间使用^字符,例如正则表达式[^269A-Z] 将匹配除了2、6、9和所有大写字母之外的任何字符。

\< \>
 

匹配词(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+匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。

?
 

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

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

匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]\{3\} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: