shell之正则表达式

引言&&grep

以前我们用grep在一个文件中找出包含某些字符串的行,比如在头文件中找出一个宏定义。其实grep还可以找出符合某个模式(Pattern)的子类字符串。例如找出所有符合xxxxx@xxxx.xxx模式的字符串(也就是email地址),要求x字符可以是字母、数字、下划线、和数点或减号,email地址的每一部分可以有一个或多个x字符,例如abc.d@ef.com1_2@987-6.54,当然符合这个模式的不全是合法的email地址,但至少可以做一次初步筛选,筛掉a.bc@d等肯定不是email地址的字符串。再比如,找出所有符合yyy.yyy.yyy.yyy模式的字符串(也就是IP地址),要求y0-9的数字,IP地址的每一部分可以有1-3y字符。

规定某些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。例如email地址正则表达式可以写成[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+,IP地址的正则表达式可以写成[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}。我们先看看正则表达式在grep中怎么用。

例如有这样一个文本文件testfile:

192.168.1.1

1234.234.04.5678

123.4234.045.678

abcde

$ egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' testfile

192.168.1.1

1234.234.04.5678

egrep相当于grep -E,表示采用Extended正则表达式语法。grep的正则表达式 有BasicExtended两种规范,另外还有fgrep命令,相当于grep - F,表示只搜索固定字符串不搜索正则表达式模式,不会按正则表达式的语法解释后面的参数。192.168.1.1符合上述模式,由三个.隔开的四段组成,每段都是13个数字,所以这一行被找出来了,可为什么1234.234.04.5678也被找出来了呢?因为grep找的是包含某个模式的行,这行不包含一个符合模式的字符串234.234.04.567。相反,123.4234.045.678这一行不包含符合模式的字符串,所以不会被找出来。

   grep是一种查找过滤工具,正则表达式在grep中用来查找符合模式的字符串。其实正则表达式还有一个重要的应用是验证用户输入是否合法,例如用户通过网页表单提交自己的email地址,就需要用程序验证一下是不是合法的email地址。

 

字符类(Character Class):如上例的xy,它们在模式中表⽰⼀个字符,但是取值范围是⼀类字符中的任意⼀个。


数量限定符(Quantifier): 邮件地址的每⼀部分可以有⼀个或多个x字符,IP地址的每⼀部可以有1-3y字符


位置限定符(Anchor):描述各种字符类以及普通字符之间的位置关系,例如邮件地址分三部分,⽤普通字符@.隔 开,IP地址分四部分,.隔开,每⼀部分都可以用字符类和数量限定符描述。


注意:

1.注意正则表达式参数用单引号括起来了,因为正则表达式中用到的很多特殊字符在Shell

也有特殊含义(例如\),只有用单引号括起来才能保证这些字符原封不动地传给grep命令,而不会被Shell解释掉。

2.再次注意grep找的是包含某⼀模式的行,而不是完全匹配某⼀模式的行。查找a*这个模式的结果是三行都被找出来了a*匹配0个或多个a,而第三行包含0a,所以也包含了这一模式。单独⽤用a*这样的正则表达式做查找没什么意义,一般是把a*作为正则表达式的一部分来用。

3.位置限定符可以帮助grep更准确地查找,

4.以上介绍的是grep正则表达式的Extended规范,Basic规范也有这些语法,只是字符?+{}|()应解释 为普通字符,要表⽰上述特殊含义则需要加\转义。如果⽤用grep而不是egrep,并且不加-E参数,则应该遵照Basic 规范来写正则表达式一定要注意!!!!!)

 

sed基本概念

     sed为流编译器,就是把前一个程序输入引入sed的输出,经过一系列编辑命令转换成另一种格式输出,在shell脚本和makefile中作为过滤器使用非常普遍。

    sed处理的⽂件既可以由标准输⼊重定向得到,也可以当命令⾏参数传⼊,命令⾏参数可以一次传⼊多个⽂件,sed会依次处理。sed的编辑命令可以直接当命令⾏参数传⼊,也可以写成⼀个脚本⽂件然后⽤-f参数指定,编辑命令的格式为

/pattern/action其中pattern是正则表达式,action是编辑操作。sed程序⼀⾏⼀行读出待处理⽂文件,如果某⼀⾏与pattern匹配,则执⾏相应的action,如果一条命令没有pattern⽽只有action,这个action将作⽤于待处理⽂件的每一⾏。sed是⼀种在线编辑器,它⼀次处理⼀⾏内容。处理时,把当前处理的⾏存储在临时缓冲

区中,称为“模式空间”(pattern space),接着⽤sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一⾏,这样不断重复,直到⽂件末尾。⽂件内容并没有改变,除⾮你使⽤重定向存储输出。Sed主要⽤来⾃自动编辑⼀个或多个⽂件;简化对⽂件的反复操作;sed默认安照Basic 规范基本匹配!

 

1./pattern/p :打印匹配pattern的行

   使用p命令需要注意sed是把待处理文件的内容连通处理结果一起输入到标准输出的,所以p除了打印文件内容还额外打印一遍匹配正则表达式的行,但是如果只想输出处理结果加上-n,这种用法相当于grep命令

2./pattern/d :删除匹配正则表达式的行,但是请注意sed命令不会修改原文件,删除命令只表示某些行不打印出来,而不是从原文件中删除。

3./pattern/s/pattern1/pattern2/:查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2

4. /pattern/s/pattern1/pattern2/g:查找符合pattern的⾏,将该⾏所有匹配

pattern1的字符串替换为pattern2

5.sed -i : 做的操作会修改原⽂件

6.定址:定址⽤于决定对哪些⾏进⾏编辑。地址的形式可以是数字、正则表达式、或⼆者的结合。如果没有指定地址,sed将处理输⼊⽂件的所有⾏。

sed -n 3pfile #打印第三⾏

sed -n 100,300pfile #打印100300⾏的信息(包括100300)地址是逗号分隔的,那么需要处理的地址是这两行之间的范围(包括这两行在内)。范

围可以⽤数字、正则表达式、或⼆者的组合表⽰。

sed 25dfile #删除第⼆⾏到第五⾏

sed /start/ ,/end/dfile #删除包含’start’⾏和’end’⾏之间的⾏

sed /start/, 10dfile #删除包含’start’ 的⾏到第⼗⾏的内容

7. 命令和选项

sed命令告诉sed如何处理由地址指定的各输⼊⾏,如果没有指定地址则处理所有的输⼊⾏。

命令

a\ :在当前⾏后添加⼀⾏或多⾏。多⾏时除最后⼀⾏外,每⾏末尾需⽤“\”续⾏

c\ :⽤此符号后的新⽂本替换当前⾏中的⽂本。多⾏时除最后⼀⾏外,每⾏末尾需⽤用”\"续⾏

i\ :在当前⾏之前插⼊⽂本。多⾏时除最后⼀⾏外,每⾏末尾需⽤”\"续⾏d删除⾏

h : 把模式空间⾥的内容复制到暂存缓冲区

H :把模式空间⾥的内容追加到暂存缓冲区

g :把暂存缓冲区⾥的内容复制到模式空间,覆盖原有的内容

G:把暂存缓冲区的内容追加到模式空间⾥,追加在原有内容的后⾯

l :列出⾮打印字符

p :打印⾏

q :结束或退出sed

r :从⽂件中读取输⼊⾏

! : 对所选⾏以外的所有⾏应⽤命令

s :⽤用⼀个字符串替换另⼀个

g :在⾏内进⾏全局替换

w :将所选的⾏写⼊⽂件

x :交换暂存缓冲区与模式空间的内容

y :将字符替换为另⼀字符(不能对正则表达式使⽤y命令)选项

-e :进⾏多项编辑,即对输⼊⾏应⽤多条sed命令时使⽤

-n :取消默认的输出

-f :指定sed脚本的⽂文件名

8. 退出状态

sed不向grep⼀样,不管是否找到指定的模式,它的退出状态都是0。只有当命令存在语法错误时,sed的退出状态才不是0

 

正则表达式:与grep⼀样,sed也⽀持殊元字符,来进行模式查找、替换。不同的是,sed使⽤的正则表达式是括在斜杠线"/"之间的模式。如果要把正则表达式分隔符"/"改为另⼀个字符,⽐如o,只要在这个字符前加⼀个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:sed -n '\o^Myop' datafile

 

 

  ^:⾏⾸定位符:/^my/ 匹配所有以my开头的⾏

  $:⾏尾定位符:/my$/ 匹配所有以my结尾的⾏

  .:匹配除换⾏符以外的单个字符: /m..y/ 匹配包含字⺟m,后跟两个任意字符,再跟字母y的⾏

  *:匹配零个或多个前导字符:/test*/ 匹配包含string tes,后跟零个或多个t字⺟的⾏

  []:匹配指定字符组内的任⼀字符 :/t[eE]st/ 匹配包含testtEst的⾏

  [^]:匹配不在指定字符组内的任⼀字符:/t[^eE]st/ 匹配string t开头,但st之前的那个字符不是eE的⾏

  \(..\):保存已匹配的字符: 标记元字符之间的模式,并将其保存为标签1,之后可以使⽤\1来引⽤它。最多可以定义9个标签,从左边开始编号,最左边的是第⼀个。此例中,对第1到第3⾏进行处理,tes被保存为标签1,如果发现tes,则替换为testttt

  &:保存查找串以便在替换串中引⽤:s/test/*&*/g 符号&代表查找串。test将被替换为*test*

  \<:词⾸首定位符:/\<my/ 匹配包含以my开头的单词的⾏

  \>:词尾定位符:/my\>/ 匹配包含以my结尾的单词的⾏

  x\{m\}:连续mx/9\{5\}/ 匹配包含连续59的⾏

  x\{m,\}:⾄少mx/9\{5,\}/ 匹配包含⾄少连续59的⾏

  x\{m,n\}:⾄至少m个,但不超过nx/9\{5,7\}/ 匹配包含连续579的⾏

 

模式空间保持空间

     sed在正常情况下,将处理的⾏读⼊模式空间(pattern space),脚本中的“sed-commandsed命令)”就⼀条接着⼀条进⾏处理,直到脚本执⾏完毕。然后该⾏被输出,模式(pattern space)被清空;接着,在重复执⾏刚才的动作,⽂件中的新的⼀⾏被读⼊,直到⽂件处理完毕。⼀般情况下,数据的处理只使⽤模式空间(pattern space),按照如上的逻辑即可完成主要任务。但是某些时候,使⽤通过使⽤保持空间(hold space),还可以带来意想不到的效果。

模式空间:可以想成⼯程⾥⾯的流⽔水线,数据直接在它上⾯进⾏处理。

保持空间:可以想象成仓库,我们在进⾏数据处理的时候,作为数据的暂存区域。

正常情况下,如果不显⽰使⽤某些⾼级命令,保持空间不会使⽤到!

sed命令:

+ g[address[,address]]g hold space中的内容拷⻉到pattern space中,原来pattern space⾥的内容清除

+ G[address[,address]]G hold space中的内容appendpatternspace\n

+ h[address[,address]]h pattern space中的内容拷⻉到hold space中,原来的hold space⾥的内容被清除

+ H[address[,address]]H pattern space中的内容appendholdspace\n

+ d[address[,address]]d 删除pattern中的所有⾏,并读⼊下⼀新⾏到pattern

+ D[address[,address]]D 删除multiline pattern中的第⼀⾏,不读⼊下⼀⾏

+ x:交换保持空间和模式空间的内容

 

 

 

awk基本使用

sed以⾏为单位处理⽂件,awksed强的地⽅在于不仅能以⾏为单位还能以列为单位处理⽂件。awk缺省的⾏分隔符是换⾏,缺省的列分隔符是连续的空格和Tab,但是⾏分隔符和列分隔符都 可以⾃定义,⽐如/etc/passwd⽂件的每⼀⾏有若⼲个字段,字段之间以:分隔,就可以重新定义awk的列分隔符为:并以列为单位处理这个⽂件。awk实际上是⼀门很复杂的脚本语⾔,还有像C语⾔⼀样的分⽀支和循环结构,但是基本⽤法和sed类似。和sed⼀样,awk处理的⽂件既可以由标准输⼊重定向得到,也可以当命令⾏参数传⼊,编辑命令可以直接当命令⾏参数传⼊,也可以⽤-f参数指定⼀个脚本⽂件。和sed类似,pattern是正则表达式,actions是⼀系列操作。awk程序⼀⾏⼀⾏读出待处理⽂件,如果某⼀⾏与pattern匹配,或者满⾜condition条件,则执⾏相应的actions,如果⼀条awk命令只有actions部分,actions作⽤于待处理⽂件的每⼀⾏。

 

awk的调用方式

1.命令⾏⽅式

awk [-F field-separator] 'commands' input-file(s)其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的⽂件。在awk中,⽂件的每⼀⾏中,由域分隔符分开的每⼀项称为⼀个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

2.shell脚本方式

将所有的awk命令插⼊⼀个⽂件,并使awk程序可执⾏,然后awk命令解释器作为脚本的⾸⾏,⼀遍通过键⼊脚本名称来调⽤。相当于shell脚本⾸⾏的:#!/bin/sh可以换成:#!/bin/awk -f

3.将所有的awk命令插⼊⼀个单独⽂件,然后调⽤:awk -f awk-script-file input-file(s)其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上⾯的是⼀样的。

 

awk调用正则表达式的方法

A.awk语句:

awk /REG/{action}/REG/为正则表达式,可以将$0中,满⾜条件记录送⼊到:action进⾏处理

B. awk正则运算语句(〜~,〜~!等同!〜~)

C. awk内置使⽤用正则表达式函数

gsub( Ere, Repl, [ In ] )

sub( Ere, Repl, [ In ] )

match( String, Ere )

split( String, A, [Ere] )

 

 

BEGINEND

awk工作流程是这样的:先执⾏BEGIN,然后读取⽂件,读⼊有\n换⾏符分割的⼀条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表⽰所有域,$1表⽰第⼀个域,$n表⽰第n个域,随后开始执⾏模式所对应的动作action。接着开始读⼊第⼆条记录·····直到所有的记录都读完,最后执⾏END操作。

 

awk内置变量

ARGC 命令⾏参数个数

ENVIRON ⽀持队列中系统环境变量的使⽤

FILENAME awk浏览的⽂件名

FNR 浏览⽂件的记录数

FS 设置输⼊域分隔符,等价于命令⾏ -F选项

NF 浏览记录的域的个数

NR 已读的记录数

OFS 输出域分隔符

ORS 输出记录分隔符

RS 控制记录分隔符

 

printprintf

    awk中同时提供了printprintf两种打印输出的函数。其中print函数的参数可以是变量、数值或者字符串。字符串必须⽤双引号引⽤,参数⽤逗号分隔。如果没有逗号,参数就串联在⼀起⽽⽆法区分。这⾥,逗号的作⽤与输出⽂件的

分隔符的作⽤是⼀样的,只是后者是空格⽽已。printf函数,其⽤法和c语⾔中printf基本相似,可以格式化字符串,输出复杂时,printf更加好⽤,代码更易懂。

 

awl数组

因为awk中数组的下标可以是数字和字⺟,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的⼀张针对key/value应⽤hash的表格⾥。由于hash不是顺序存储,因此在显⽰数组内容时会发现,它们并不是按照你预料的顺序显⽰出来的。数组和变量⼀样,都是在使⽤时⾃动创建的,awk也同样会⾃动判断其存储的是数字还是字符串。⼀般⽽⾔,awk中的数组⽤来从记录中收集信息,可以⽤于计算总和、统计单词以及跟踪模板被匹配的次数等。

 

CUT

定义:正如其名,cut的⼯作就是“剪”,具体的说就是在⽂件中负责剪切数据⽤的。cut是以每⼀行为⼀个处理对象的,这种机制和sed是⼀样的。

cut命令主要是接受三个定位⽅法:

第⼀,字节(bytes),⽤选项-b

第⼆,字符(characters),⽤选项-c字符cut相对⽐比较简单,中⽂字符和空格都算⼀个字符。

第三,域(fields),⽤选项-f-d指定域分隔符,-f 指定要剪出哪⼏个域,这个与awk的输出特定字段功能⼀样。

 

 

Sort

1. sort将⽂件的每⼀⾏作为⼀个单位,相互⽐较,⽐较原则是从⾸字符向后,依次按ASCII码值进⾏⽐较,最后将他们按升序输出。

2. sort-u选项它的作⽤很简单,就是在输出⾏中去除重复⾏

3. sort-r选项sort默认的排序⽅式是升序,如果想改成降序,就加个-r就搞定了。

4.  sort-o选项由于sort默认是把结果输出到标准输出,所以需要⽤重定向才能将结果写⼊⽂件,形如sortfilename > newfile。但是,如果你想把排序结果输出到原⽂件中,⽤重定向可就不⾏了

5.  sort-n选项你有没有遇到过102⼩的情况。我反正遇到过。出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先⽐较12,显然1⼩,所以就将10放在2前⾯喽。这也是sort的⼀贯作风。我们如果想改变这种现状,就要使⽤用-n选项,来告诉sort,“要以数值来排序”!

6. sort-t选项和-k选项 sort提供了-t选项,后⾯可以设定间隔符。 指定了间隔符之后,就可以⽤用-k来指定列数了

7.  其他的sort常⽤选项-

f会将⼩写字母都转换为⼤写字母来进行比较,亦即忽略⼤⼩写

-c会检查⽂件是否已排好序,如果乱序,则输出第⼀个乱序的⾏的相关信息,最后返回1

-C会检查⽂件是否已排好序,如果乱序,不输出内容,仅返回1

-M会以⽉份来排序,⽐如JAN⼩于FEB

-b会忽略每⼀⾏前⾯的所有空⽩部分,从第⼀个可见字符开始⽐较。

 

Unip

说明:这个命令读取输⼊⽂件,并⽐较相邻的⾏行。在正常情况下,第⼆个及以后更多个重复⾏将被删去,⾏⽐较是根据所⽤字符集的排序列进⾏的。该命令加⼯后的结果写到输出⽂件中。输⼊⽂件和输出⽂件必须不同。如果输⼊⽂件⽤- ”表⽰,则从标准输⼊读取。

该命令各选项含义如下:、

c 显⽰输出中,在每⾏⾸加上本⾏在⽂件中出现的次数。它可取代- u- d

选项。

d 只显⽰重复⾏。

u 只显⽰⽂件中不重复的各⾏。










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值