一、什么是正则表达式

正则表达式就是处理字符串的方法,它是以行为单位来进行字符串的处理行为,正则表达式通过一些特殊符号的帮助,可以让用户轻松达到“搜索/删除/替换”某特定字符串的处理程序。

正则表达式的字符串表示方法依照严谨程度的不同分为基础正则表达式和扩展正则表达式。

正则表达式和通配符是完全不一样的。通配符代表的是bash界面的功能,而正则表达式表示的是一种字符串的表示方式。

二、基础的正则表达式

正则表达式是处理字符串的一种表达式,对字符排序有影响的语系数据就会对正则表达式的结果有影响。正则表达式也需要支持工具程序来辅助才可以。

1.语系对正则表达式的影响

实际是我们看到的字符文字和数字都是编码表转换来的,由于不同语系编码数据不同,所以会造成数据选取的结果差别。

使用正则表达式的时候,需要特别留意语系环境是什么,否则可能会出现不符合自己需求的结果。

一些特殊的符号了解一下。

特殊符号代表意义
[:alnum:]代表英文大小写字符及数字,亦即0-9,A-Z,a-z
[:alpha:]代表任何英文大小写字符,亦即A-Z,a-z
[:blank:]代表空格键与[Tab]按键两者
[:cntrl:]代表键盘上面的控制按键,亦即包括CR,LF,Tab,Del..等等
[:digit:]代表数字而已,亦即0-9
[:graph:]除了空格符(空格键与[Tab]按键)外的其他所有按键
[:lower:]代表小写字符,亦即a-z
[:print:]代表任何可以被打印出来的字符
[:punct:]代表标点符号(punctuationsymbol),亦即:"'?!;:#$...
[:upper:]代表大写字符,亦即A-Z
[:space:]任何会产生空白的字符,包括空格键,[Tab],CR等等
[:xdigit:]代表16进位的数字类型,因此包括:0-9,A-F,a-f的数字与字符

(1)grep的一些高级参数

[dmtsai@study ~]$ grep [-A] [-B] [--color=auto] '搜尋字串' filename

选项与参数:

-A:后面可加数字,为after的意思,除了列出该行外,后续的n行也列出来;

-B:后面可加数字,为befer的意思,除了列出该行外,前面的n行也列出来;

--color=auto可将正确的那个撷取数据列出颜色。

(2)基础正则表达式字符(characters)

RE字符意义与范例
^word意义:待搜寻的字符串(word)在行首!
:行首为#开始的那一行,并列出行号grep-n'^#'regular_express.txt
word$意义:待搜寻的字符串(word)在行尾!
范例:将行尾为!的那一行打印出来,并列出行号

grep-n'!$'regular_express.txt

.意义:代表『一定有一个任意字符』的字符!
范例:搜寻的字符串可以是(eve)(eae)(eee)(ee),但不能仅有(ee)!亦即e与e中间『一定』仅有一个字符,而空格符也是字符!

grep-n'e.e'regular_express.txt

\意义:转义字符,将特殊符号的特殊意义去除!
范例:搜寻含有单引号'的那一行!

grep-n\'regular_express.txt

*意义:重复零个到无穷多个的前一个RE字符
范例:找出含有(es)(ess)(esss)等等的字符串,注意,因为*可以是0个,所以es也是符合带搜寻字符串。另外,因为*为重复『前一个RE字符』的符号,因此,在*之前必须要紧接着一个RE字符喔!例如任意字符则为『.*』!

grep-n'ess*'regular_express.txt

[list]意义:字符集合的RE字符,里面列出想要撷取的字符!
范例:搜寻含有(gl)或(gd)的那一行,需要特别留意的是,在[]当中『谨代表一个待搜寻的字符』,例如『a[afl]y』代表搜寻的字符串可以是aay,afy,aly即[afl]代表a或f或l的意思!

grep-n'g[ld]'regular_express.txt

[n1-n2]意义:字符集合的RE字符,里面列出想要撷取的字符范围!
范例:搜寻含有任意数字的那一行!需特别留意,在字符集合[]中的减号-是有特殊意义的,他代表两个字符之间的所有连续字符!但这个连续与否与ASCII编码有关,因此,你的编码需要设定正确(在bash当中,需要确定LANG与LANGUAGE的变量是否正确!)例如所有大写字符则为[A-Z]

grep-n'[A-Z]'regular_express.txt

[^list]意义:字符集合的RE字符,里面列出不要的字符串或范围!
范例:搜寻的字符串可以是(oog)(ood)但不能是(oot),那个^在[]内时,代表的意义是『反向选择』的意思。例如,我不要大写字符,则为[^A-Z]。但是,需要特别注意的是,如果以grep-n[^A-Z]regular_express.txt来搜寻,却发现该文件内的所有行都被列出,为什么?因为这个[^A-Z]是『非大写字符』的意思,因为每一行均有非大写字符,例如第一行的"OpenSource"就有p,e,n,o....等等的小写字

grep-n'oo[^t]'regular_express.txt

\{n,m\}意义:连续nm个的『前一个RE字符』
意义:若为\{n\}则是连续n个的前一个RE字符,
意义:若是\{n,\}则是连续n个以上的前一个RE字符!范例:在g与g之间有2个到3个的o存在的字符串,亦即(goog)(gooog)

grep-n'go\{2,3\}g'regular_express.txt

(2)sed工具

sed 本身也是一个管道命令,可以分析standard input的啦!而且sed还可以将数据进行替换、删除、新增、选取特定行等等的功能。

其使用方式如下:

 

三、扩展的正则表达式法

RE字符意义与范例
+意义:重复『一个或一个以上』的前一个RE字符
范例:搜寻(god)(good)(goood)...等等的字符串。那个o+代表『一个以上的o』所以,底下的执行成果会将第1,9,13行列出来。

egrep-n'go+d'regular_express.txt

?意义:『零个或一个』的前一个RE字符
范例:搜寻(gd)(god)这两个字符串。那个o?代表『空的或1个o』所以,上面的执行成果会将第13,14行列出来。有没有发现到,这两个案例('go+d'与'go?d')的结果集合与'go*d'相同?想想看,这是为什么喔!^_^

egrep-n'go?d'regular_express.txt

|意义:用或(or)的方式找出数个字符串
范例:搜寻gd或good这两个字符串,注意,是『或』!所以,第1,9,14这三行都可以被打印出来喔!那如果还想要找出dog呢?

egrep-n'gd|good'regular_express.txt
egrep-n'gd|good|dog'regular_express.txt

()意义:找出『群组』字符串
范例:搜寻(glad)或(good)这两个字符串,因为g与d是重复的,所以,我就可以将la与oo列于()当中,并以|来分隔开来,就可以啦!

egrep-n'g(la|oo)d'regular_express.txt

()+意义:多个重复群组的判别
范例:将『AxyzxyzxyzxyzC』用echo叫出,然后再使用如下的方法搜寻一下!

echo'AxyzxyzxyzxyzC'|egrep'A(xyz)+C'

 

四、文件格式化与相关处理

1.格式化打印:printf

使用方法如下:

[dmtsai@study ~]$ printf '打印格式' 实际内容

选项与参数:

\a:警告声音输出

\b:退格键(backspace)

\f:清除屏幕(formfeed)

\n:输出新的一行

\r:亦即Enter按键

\t:水平的[tab]按键

\v:垂直的[tab]按键

\xNN:NN为两位数的数字,可以转换数字成为字符。

关于C程序语言内,常见的变数格式

%ns:那个n是数字,s代表string,亦即多少个字符;

%ni:那个n是数字,i代表integer,亦即多少整数字数;

%N.nf:那个n与N都是数字,f代表floating(浮点)

使用实例如下:

范例一:将刚刚上头数据的文件 (printf.txt) 内容仅列出姓名与成绩:(用 [tab] 分隔)

[dmtsai@study ~] printf '%s\t %s\t %s\t %s\t %s\t \n' (cat printf.txt)

Name     Chinese         English         Math    Average

DmTsai   80      60      92      77.33

VBird    75      55      80      70.00

Ken      60      90      70      73.33

 

2.awk:好用的数据处理工具

使用方式如下:

[dmtsai@study ~]$ awk '条件类型1{动作1} 条件类型2{动作2} ...' filename

awk后面接两个但银行和大括号来设置下要对资料进行的操作。awk可以处理后续接的文件,也可以读取来自前面指令的标准输出。awk主要是处理每一行的字段内的数据,而默认的字段的分隔符为空格键或者TAB

每一行的每个字段都是有变量名称的,那就是 1, 2... 等变量名称。

$0代表一整列资料。

awk怎样知道这个数据有几行几列呢?需要内置变量来帮忙。

变量名称代表意义
NF每一行 ($0) 拥有的字段总数
NR目前 awk 所处理的是『第几行』数据
FS目前的分隔字符,默认是空格键

awk的运算符号如下:

运算单元代表意义
>大于
<小于
>=大于或等于
<=小于或等于
==等于
!=不等于

 

3.文件比较工具

(1)diff

diff就是用在比对两个文件之间的差异的,并且是以行为单位来比对的!一般是用在ASCII纯文本档的比对上。由于是以行为比对的单位,因此diff通常是用在同一的文件(或软件)的新旧版本差异上。

其使用方法如下所示:

[dmtsai@study ~]$ diff [-bBi] from-file to-file

选项与参数:

from-file:一个文件名,作为原始比对文件的文件名;

to-file:一个文件名,作为目的比对文件的文件名;

注意,from-file或to-file可以-取代,那个-代表『Standard input』之意。

-b:忽略一行当中,仅有多个空白的差异(例如"about me"与"about    me"视为相同

-B:忽略空白行的差异。

-i:忽略大小写的不同。

(2)cmp

cmp主要也是在比对两个文件,他主要利用“字节”单位去比对,因此,当然也可以比对binary file。

使用方法如下:

[dmtsai@study ~]$ cmp [-l] file1 file2

选项与参数:

-l:将所有的不同点的字节处都列出来。因为cmp预设仅会输出第一个发现的不同点。

(3)patch

如果将旧的文件更新为新的文件,应该如何去做呢?就要先比较新旧文件的版本差异,然后将差异制作成补丁文件,再由补丁文件更新旧文件即可。

[dmtsai@study ~] patch -pN < patch_file    <==更新 [dmtsai@study ~] patch -R -pN < patch_file <==还原

选项与参数:

-p  :后面可以接『取消几层目录』的意思。

-R  :代表还原,将新的文件还原成原来旧的版本。

 

4.文件打印准备

如果你曾经使用过一些图形接口的文字处理软件的话,那么很容易发现,当我们在打印的时候,可以同时选择与设定每一页打印时的标头吧!也可以设定页码。那么,如果我是在Linux底下打印纯文本档呢可不可以具有标题啊?可不可以加入页码啊?呵呵!当然可以啊!使用pr就能够达到这个功能了。不过,pr的参数实在太多了。举例来说,如果想要打印/etc/man_db.conf呢?

[dmtsai@study ~]$ pr /etc/man_db.conf

2014-06-10 05:35                 /etc/man_db.conf                 Page 1

#

#

# This file is used by the man-db package to configure the man and cat paths.

# It is also used to provide a manpath for those without one by examining

# configure script.

上面特殊字体那一行呢,其实就是使用pr处理后所造成的标题啦!标题中会有『文件时间』、『文件名』及『页码』三大项目。更多的pr使用,请参考pr的说明。