shell脚本之查找与替换(一)

时间:2022-12-10 14:58:35

文本查找(searching)与文本替换(substitution)是编写shell脚本时经常用到的两个基本操作。

查找文本

传统上,有三种程序可以用来查找整个文本文件:grep, egrep(Extended grep), fgrep(Fast grep)。
grep最简单的用法就是使用固定字符串,例如who | grep -F cosette 可以查找登陆名为cosette的用户。

grep
语法: grep [options...] pattern-spec [files...]
用途:显示匹配一个或多个模式的文本行。通常作为管道的第一步。
主要选项:
-E %使用扩展正则表达式进行匹配
-F %使用固定字符串进行匹配
-e pat-list %
-f pat-file %从pat-file文件读取模式作匹配
-i %模式匹配时忽略字母大小写差异
-l %列出匹配模式的文件名称
-q %静默地
-s %不显示错误信息,通常与-q并用
-v %显示不匹配模式的行

正则表达式

常用的正则表达式元字符

元字符(meta) 模式含义
\ 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配\n。“\n”匹配换行符。序列“\”匹配“\”而“(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。
^ 匹配紧接着的正则表达式,在行或字符串的起始处
$ 匹配前面的正则表达式,在行或字符串的结尾处
. 匹配任何单个的字符,但NULL除外
* 匹配在它之前的任何数目(或没有)的单个字符所以.*代表匹配任一字符的任意长度
[] 匹配方括号内的任一字符
+ 匹配前面正则表达式的一个或多个实例
? 匹配前面正则表达式的零个或一个实例
| 匹配于|符号前或后的正则表达式
() 匹配于括号括起来的正则表达式群
{n} n是一个非负整数。匹配确定的n次,注意在使用过程中是否需要使用转义字符\{
{n,} n是一个非负整数。至少匹配n次
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次

简单的正则表达式匹配范例:

表达式 匹配
tolstoy 位于任何一行上任何位置的7个字母:tolstoy
^tolstoy 7个字母tolstoy,出现在一行的开头
tolstoy$ 7个字母tolstoy,出现在一行的结尾
^tolstoy$ 正好包括tolstoy这7个字母的一行,没有其他的任何字符
[Tt]olstoy 在一行的任意位置上,含有Tolstoy或tolstoy
tol.toy 在一行的任意位置上,含有tol这3个字母,加上任何一个字符,再接着toy3个字母
tol.*toy 在一行的任意位置中,含有tol这3个字母,加上任意的0或多个字符,在继续toy这3个字母

POSIX方括号表达式:
POSIX是为了配合非英语环境,强化其字符集范围的能力,另有额外的组成部分。:

基本正则表达式

匹配单个字符

匹配单个字符,一般有四种表示方式,一般字符,转义的meta字符,.meta字符,还有方括号表达式。需要注意的是,在方括号表达式中,^放在字首表示取反。例[^aeiou] 指的就是小写原因字符以外的任何字符。

  • 排序: 用[..] 括起来
    例如,[ab[.ch.]de] 匹配于字符a,b,d或e,或者是成对的ch。
  • 等价字符集:用[==]
    正则表达式[a[=e=]iou]就等同于所有的小写字母元音以及法文字母e,e(有音调)
    特殊字符集:需要特别指出的是,要让]进入集合,可以将它放在列表的最前面[.]*.],要让减号进入该集合,也需要把它放到列表最前端[.-*.],如果需要同时右方括号和减号,[.]*.-]。

后向引用

关于后向引用,我个人的理解是可以直接写出前面出现过的正则表达式的位置直接使用。它的使用分为两个部分,第一步, 将子表达式包围在\(与\)里,单个模式最多可包含9个子表达式,且可为嵌套结构。
第二步是在统一模式后使用\digital,digital指的是介于1到9之间的数字,指的是匹配于第n个先前方括号内子表达式匹配成功的字符。
例:

模式 匹配成功
\(ab\)\(cd\)[def]*\2\1 abcdcdab abcdeeecdab abcd ddeeffcdab
\(why\).*\1 一行里重现两个why
\([[:alapha:]_]][[:alnum]_]*\)=\1; 简易C/C++赋值语句

注:

后向引用在寻找重复字以及匹配引号时特别好用:
\(["']\).*\1 匹配以单引号或双引号括起来的字,例如”fool”,’bye’