Shell脚本学习指南-查找与替换

时间:2022-04-18 08:56:11

##查找文本

  grep程序查找文本,有三种程序grep、egrep(扩展的grep,功能更强大,不过更耗时)、fgrep(快速grep,可以并行匹配,但只匹配固定字符串)。现在POSIX标准已经将三者合并,并通过不同的参数进行选择。

###正则表达式

   正则表达式由两个基本组成部分:一般字符和特殊字符,后者通常称为元字符(即可以表示其它字符的字符)。

   后向引用:匹配正则表达式先前已匹配的部分,分两步:1将子表达式包围在/(和)/里,最多9个,可以嵌套。2/digit引用,数字为1-9,表示前方第N个匹配成功的字符。

   修饰符元字符(*,+等)

   区间表达式q/{n/}n个q、q/{n,/}至少n个q,q/{n,m/}n到m个q

   文本匹配锚点,注意是以行为单位的(^行开头,$行结尾)

练习:

   1.功能:过滤到文本中的空行

     cat a.txt|grep -v ^$ >b.txt;cat b.txt > a.txt;rm -rf b.txt

###扩展正则表达式

   后向引用不存在,/(和/)表示字面上的括号

   交替:使用|分割开来的字符

   分组:在()提供分组功能,(why)+

   停驻文本匹配:ERE中^和$永远是元字符,而不管它在表达式的*或者首末。

###正则表达式的扩展

   /< />运算符,前者表示单词的开头,后者表示结尾。

   /w等于[[:alnum:]_]

   /W等于[^[:alnum:]_]

   /b只匹配单词首尾空字符

   /B只匹配单词之间的空字符

###在文本文件里进行替换

   sed: 

       -e 命令,可接多命令

       -f 命令脚本,一般用于多个命令时

       -n 只显示p指定的行。

####替换细节

   &在替代文本中的意思是“从此点开始替代成匹配于正则表达式的整个文本”。

   要在替代文本中使用字符&的字面意义,需要使用转义字符/

   s命令中以g表示:全局替换。

   每一个编辑命令都使用一个-e选项

####sed的运作   

   一次读取一行,将读取的行放在内存的一个区域(模式空间),所有的编辑都在模式空间上,操作完成后输出到标准输出。

####匹配特定的行

   以五种方式:

       1.将一模式放在一条命令前,可以限制命令应用于匹配模式的行。如:/oldfunc/ s/$/#XXX:migrate tonewfunc/

       2.符号$指最后一行。如:sed -n '$p' "$1",只显示最后一行,引号内为第一个输入参数。

       3.可以使用绝对的行编号,作为地址。sed -n '10p' foo.xml

       4.也可以使用行的范围。如:sed -n '10,42p' foo.xml

       5.可使用否定正则表达式,表示将命令应用于不匹配于特定模式的一行。如:/used/!s/new/used/g 将没有used的每个行里所有的new改成used。

    改变默认定界符:通过在字符前面使用转义字符/。如:echo a:b:c:|sed -n '/:a: s;;A;p',此处;;之间的空位表示使用前一个匹配模式。   

#####有多少文本改动

    规则:POSIX标准指出:“完全一致的匹配 ,指的是自最左边开始匹配、针对每一个子模式、由左至右,必须匹配到最长的可能字符串”。

###使用cut选定字段

    cut命令是用来剪切文本文件里的数据,文本文件要可以是字段类型或是字符类型。

    -c list 以字符为主,执行剪切操作。如1,3,5-12分别表示第1,3列字符,5-12列字符。

    -d delim 使用delim作为定界符,默认为制表字符tab

    -f list 以字段为主,作剪切操作。

###使用join连接字段

   类似于集合,一般是先排序,后join。

 

###使用awk重新编排字段

   最常用的功能:做一些简易的文本处理。

 

####模式与操作

   awk 'program' [file ...],其中program为:pattern {action},两者都忽略。表达式的意思为:如果每个pattern为真,则执行action内的程序代码。

   可以通过设置FS变量的值选择新的分割字段,可以是完整的ERE,默认为空白。当然,也可以通过 -F选项修改。

   awk将每条记录内的字段数目,存储在内部变量NF中。

   通过设置OFS变量改变输出字段分割字符。

   可使用print和printf打印。print示例:awk -F: '{print "User",$1,"is really",$5}' /etc/passwd

printf示例: awk -F: '{printf "User %s is really %s /n",$1,$5}'.需要注意的是print需要以","分割字段,而printf不需要,但printf需要显式地指定换行符/n。

   起始BEGIN和清除END:可选的,主要在awk程序的开头,结尾处。可以有多个BEGIN和END块。使用规则为:

BEGIN { 起始操作代码}

pattern1  {action1}

pattern2  {action2}

END {结束操作代码}

   awk为可编程语言。