Linux Shell之十 sed与awk

    设计script时,有时候需要修改脚本,例如删除或置换某些关键词。像这种在script执行过程动态修改文件的做法,称为流编辑。具有流编辑能力的工具,称为流编辑器。sed是这方面的强者。另外script执行时可能要制作报表,呈现各字段信息,awk完美解决。

一、正则表达式

    正则表达式是组成“样式”的基本语法,而“样式”是运用sed和awk必备的能力。sed和awk相同的运行方式是:只要符合“样式”的数据行,就对它执行指定的“操作”。

什么是正则表达式?

正则表达式是一种描述的方法,一种小型的语言,可表示某种样式或若干种样式的组合,它的威力在于仅需几个简单的字符,便可代表许多字符串共同的样子。

1、. 代表任意字符

   .a. 代表中间为a,两边随意字符的3个字符。(若要对比.本身需要用\转义)

2、^ 代表在行首

   ^abc  abd应该出现在行首。"abc,hello"和"hello abc" 前者符合后者不符合

3、$ 代表在尾部

   $abc  abd应该出现在行尾。"abc,hello"和"hello abc" 后者符合前者不符合

4、[...] 字符集合

   [...] 代表字符 串行中的一个字符 [aBc]代表a或B或c。[A-Z]一个大写[^A-Z]除了大写之外的一个字符。

5、*出现0个以上

   a*c可以是abc、abbc、abbbc、aSJKSKBKc.....

6、\{...\}指定符合的个数

   \{3,5\}前边的字符有3~5个。[a-z]\{3,5\}代表以小写字母组成的字符串,长度为3~5个

7、\(..\)把对比符合的字符串暂时保存起来

   a\(..\)b要保存a、b之间的2个字符,若要提取保存的字符串,可用位置参数,\1代表第一个保存的字符串,\2代表第二个保持的字符串。


二、扩展正则表达式

RE字符  意义与范例

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

        egrep ‘go+d‘ file 搜寻范围是 god good goood gooood......等

? 0个或1个的前一个RE字符

        egrep ‘go?d‘ file 搜寻范围 god good

|       用或(or)的方式找出字符串

        egrep ‘g(la|oo)d file 搜寻范围 glad good

()+     多个重复群组的判别

        echo "AxyzxyzxyzxyzC" |egrep ‘A(xyz)C‘ 意思是A开头,C结尾,中间有一个以上的"xyz"字符串的意思 

注意:  !在正规表达式中不是特殊字符,如果要查包含!与<的字行时, grep ‘[!>]‘ file

        [!a-z] 这样反响选择是错误的,[^a-z] 这样才是正确的。

格式化打印:printf 


三、sed的用法

sed是一种非交互式的流编辑器,可动态编辑文件。sed处理的对象是文件的数据流。sed的工作模式是对比每一数据行,若符合样式,就执行特定的操作。

sed的语法:sed‘样式命令‘文件

意思是如果文件某一行符合‘样式‘,就执行指定是的sed命令,如删除(d)或取代(s)或显示(p)。

这里的‘样式‘使用一对//含括,表示寻找之意。/1,6/第一行到第6行,/a/,/b/含有a到b的行

注意:sed并不会更改原文件内容。sed的工作方式是读取文件内容,经流编辑后,把结果显示到标准输出,如想要存储sed处理结果,要自行运用转向输出讲结果存成其它文件。

sed的选项:

sed -n 使用安静模式,在一般sed模式中,所有来自STDIN的数据一般都会被列出到屏幕上,加上-n后只有经过sed处理的那才一行才会被列出来。

    -e 直接在指令模式上进行sed的动作编辑

    -f 直接将sed动作写在一个档案内,-f filename 则可以执行filename内的sed动作。

    -r sed的动作支持延申动作表示法

    -i 直接修改档案读取的内容.(直接修改原文本内容,小心操作)

动作说明: [n1[,n2]]function 

n1,n2不见得会存在,一般代表 选择进行的动作的行数,举例来说,如果我的动作是需要在10到20行之间进行的,则10,20[动作行为] 

function 有底下这些东西:

    a: 新增, a的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)

    i :插入, i后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行);

    c :取代, c的后面可以接字符串,这些字符串可以取代 n1,n2 之间的行!

    d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;

    p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运作~

    s :取代,可以直接直接进行取代的工作!通常这个 s 的动作可以搭配 正则表示法!例如 1,20s/old/new/g 就是!

sed的语法:

sed ‘s/要取代的字符/新字符/g‘                g表示全局的意思

1、删除某一段范围的数据行

  sed ‘1,4d‘ file 把第1到第4行数据删除,剩下的显示出来。($代表最后一行‘1,$‘)

2、把含有样式的数据行删除

  sed ‘/ab/d‘ file 把含有ab的所有行删除。 sed ‘/[0-9]\{3\}/d‘ file 把含有3为数的行删除。\{3\}表示//要寻找的3个数字的字符串 sed ‘/^$/d‘ file 删除空白行

3、把不含样式的行删除

  sed ‘/ab/!d‘ 不含ab的行删除,剩下的显示出来。(或者说把涵ab的行不删除

4、把含有样式的数据行显示出来(但sed默认也显示不符合的数据行)

 sed ‘/ab/p‘ 把含有ab的行显示出来,不符合的也显示出来   -n会抑制默认显示其它行 sed -n ‘/ab/p‘ 只把含ab的行显示出来。

5、取代

 sed -n ‘s/ab/AB/p‘ file 把file中每一行第一个出现ab的字符串换位AB,sed -n ‘s/ab/AB/gp‘ file 把file中每行所有的ab都换为AB

 sed -n ‘s/ab//p‘ file 把file中每行第一个ab删除(把ab置换成空字符串就是删除)

 sed ‘s/^...//‘ file 把每一行开头的3个字符删除,如果^是$,则把每行最后3个字符删除。

6、取用符合样式的字符串

 sed -n ‘s/\(ab\)/\1cd/p‘ file 把每行第一个出现ab的字符换为abcd 。可分解为sed -n ‘s/ \(ab\) / \1cd /p 其中( ) 1之前都用\来转义,依旧是//模式

7、找到符合样式的数据后,再进行取代操作

 sed -n ‘/AAA/s/ab/AB/p‘ file 找到含有AAA的行后,把第一个出现的ab换成AB(如果是gp,就把每行出现的ab换成AB)

 sed -n ‘/aaa/,/bbb/s/123/456/gp‘  file将含有aaa到bbb的那几行,把所有的123换成456

 sed -n ‘2,4s/a/b/p‘ file  由第2行到第4行,把出现的第1个a换成b

例子:

cat /etc/passwd| sed ‘2a hello world‘

在第2行的后边加一行内容是helloworld,如果a前没有数字.就在每行后边另起一行,内容为hello world (如果前边的话用i)

cat /etc/passwd| sed ‘2i one \ two ‘ 

在第2行前边增加2行,内容分别为one、two ,每行之间要用 \(回车) 隔开

cat /etc/passwd | sed ‘2i 1 \

2 \

3 \

4 \

5‘

在第2行前边增加5行,内容分别是1 2 3 4 5

cat /etc/passwd | sed  ‘1c hello world‘  把第1行内容换为hello world

cat /etc/passwd | sed  ‘2,4c hello world‘  把第2-4行内容换为hello world

cat /etc/passwd | sed -n ‘1p‘  显示第1行 如果是 sed -n ‘2,3p‘ 为显示第2行和第3行。 sed ‘$p‘显示最后一行 

grep -v ‘^$‘ file | grep -v ‘^#‘ 和 egrep -v ‘^$|^#‘ regular_express.txt  $代表最后一行去除空白行与行首为 # 的行列 

cat /etc/passwd |sed -e ‘1d‘ -e ‘2,3c hello world‘  把第1行删除,把第2行和第3行内容换成hello world

注意:

如果sed后跟多个选项,务必使用-e参数


四、awk的用法

awk是一种可以处理数据、产生格式化报表的语言。它的工作方式是读取数据,将每一行数据视为一条记录,每笔记录以字段分隔符分成若干字段,然后输出各个字段的值。

awk对每一条记录,都会套用一个"样式{操作}",如果该行符合样式,就执行指定的操作。

样式或操作之一可以省略。如果只有样式,表示要显示符合样式的行;如果只有操作,表示对每一行数据都执行该项操作。

awk的常用的作用格式:

awk "样式"   文件:把符合样式的数据行显示出来。

awk ‘{操作}’ 文件:对每一行都执行{}中的操作。

awk ‘样式{操作}’ 对符合样式的数据行,执行{}中的操作。

awk的几种用法:

1、awk ‘/root/‘ file 

   显示file中root的行

2、awk ‘{print $1,$2}‘ file         ","可以省略如果让两个字符以空格隔开的话用 awk ‘{print $1 "\t" $2‘

   显示file中每一行的第1个和第2个字段(默认以空格为分隔符)

3、awk ‘/ab/{print $1,$2}‘ file

   显示file中有ab的行的第1个和第2个字段(以空格为分隔符)

4、awk -F: ‘/^root/{print $2,$3}‘ file

   以":"为分隔符,把以root开头的行中的第2个和第3个字符显示出来。

5、awk -F: ‘BEGIN{OFS="++++"}/^root/{print $1,$2,$3}‘ /etc/passwd 

   把passwd中,以":"为分隔符找出首行为root的行,并显示前3个字段,并且字段之间以+++隔开

实例:

变量名称 代表意义

NF 每一行$0拥有的字段总数(默认以空格或Tab为分隔符)

NR 目前awk所处理的是第几行数据

FS 目前的分隔符,默认是空格键

[root@centos ~]# cat 1
a2a3a4a5a
b2b3b4b5b
c2c3c4c5c
[root@centos ~]# cat 1|awk ‘{print $1 "\t 行:" NR "\t 该行总字段:" NF}‘
a 行:1 该行总字段:5
b 行:2 该行总字段:5
c 行:3 该行总字段:5
查阅passwd第三栏数据小于10的数据的行,并且仅列出账号和第三栏。
cat /etc/passwd|awk ‘{FS=":"}$3<10 {print $1 "\t" $3}‘  
root:x:0:0:root:/root:/bin/bash
bin1
daemon2
...
mail8

上边第一行会全部显示出来,这是因为我们读入第一行的时候,那些变数 $1, $2..默认还是以空格键为分隔的,所以虽然我们定义了 FS=":" 了, 但是却仅能在第二行后才开始生效。

那么怎么办呢?我们可以预先设定 awk 的变量啊! 利用 BEGIN 这个关键词!这样做:cat /etc/passwd|awk ‘BEGIN{FS=":"}$3<10 {print $1 "\t" $3}‘

显示ip地址

ifconfig |grep ‘inet addr‘|grep Bcast|awk ‘{print $2}‘|awk -F: ‘{print $2}‘ 

显示网络名称

cat /proc/net/dev |awk -F: ‘/eth.:|sit.:|wlan.:|ppp.:/{print $1}‘


sed与awk可以单独写出一本书,实在很强大,本篇只介绍最简单的用法。

这些都是读书笔记,接下来我们真正进入Shell实战!

本文出自 “Welcome To Linux World” 博客,请务必保留此出处http://linuxnote.blog.51cto.com/9876511/1641278

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。