您的位置:首页 > 运维架构 > Linux

鸟哥的linux私房菜_正则表达式与文件格式化处理

2018-01-04 10:06 405 查看


12 正则表达式与文件格式化处理

12.1 什么是正则表达式

12.1.1 什么是正则表达式

12.1.2 正则表达式对系统管理员的用途

12.1.3 正则表达式的广泛用户

12.1.4 正则表达式与shell在linux当中的角色定位

12.2基础正则表达式

12.2.1 语系对正则表达式的影响

12.2.2 grep的一些高级参数

>grep [-A] [-B] [--color=auto] '搜寻的字符串' 文件

-A :后面接数组,after的意思,除了列出该行外,后续的n行页也列出来

-B:后面接数组,before的意思,...,前面的n行也列出来

范例

范例一:用 dmesg 列出核心讯息,再以 grep 找出内含 qxl 那行

[dmtsai@study ~]$  dmesg | grep 'qxl'

[ 0.522749] [drm] qxl: 16M of VRAM memory size

[ 0.522750] [drm] qxl: 63M of IO pages memory ready (VRAM domain)

[ 0.522750] [drm] qxl: 32M of Surface memory size

[ 0.650714] fbcon: qxldrmfb (fb0) is primary device

[ 0.668487] qxl 0000:00:02.0: fb0: qxldrmfb frame buffer device

# dmesg 可列出核心产生的讯息!包括硬件侦测的流程也会显示出来。

# 鸟哥使用的显卡是 QXL 这个虚拟卡,透过 grep 来 qxl 的相关信息,可发现如上信息。

范例二:承上题,要将捉到的关键词显色,且加上行号来表示:

[dmtsai@study ~]$  dmesg | grep -n  --color=auto 'qxl'

515:[ 0.522749] [drm] qxl: 16M of VRAM memory size

516:[ 0.522750] [drm] qxl: 63M of IO pages memory ready (VRAM domain)

517:[ 0.522750] [drm] qxl: 32M of Surface memory size

529:[ 0.650714] fbcon: qxldrmfb (fb0) is primary device

539:[ 0.668487] qxl 0000:00:02.0: fb0: qxldrmfb frame buffer device

# 除了 qxl 会有特殊颜色来表示之外,最前面还有行号喔!其实颜色显示已经是默认在 alias 当中了!

12.2.3基础正则表达式练习

查找特定的字符
4000


>grep -n 'the' act.txt

利用中括号[]来查找特定字符

例如要查找 test 或tasts,我们发现test 和tasts有共同的 t?st

>grep -n 't[ae]st' abv.txt

要查找oo 但是前面不要是g

>grep -n '[^g]oo' acv.txt

行首与行尾字符^$

例:例1 中查找一行字符串中有the的,如果想让the只在行首出现,

>grep -n '^the' abc.txt

^在[]中括号内时代表反向选择,在中括号外代表行首的意思。注意区分

例:查找行尾的结束符为小数点的。

>grep -n '\.$' acc.txt 

小数点有特殊意义,所以用了转义符

任何一个字符与重复字符

. : (小数点),代表一定有一个任意字符的意思

*:星号,代表重复前一个0到无穷多的意思

例子:我们要找到g??d的字符,即4个字符,开头是g 结束是d;

>grep -n 'g..d' abdd.txt 

"o*" :代表 是空字符或者有一个以上的o;

"oo*" :代表至少有一个o;

限定连续RE字符范围{}

*是设置0到无穷多个,如果想要设定一个范围,例如想要2-5个连续的o。

例子:找到两个连续的o

>grep -n 'o\{2\}' ac.txt

想要2-5个连续的o

>grep -n 'o\{2,5\}'

想要2个以上的o呢

>grep -n 'o\{2,\}'

(第二个范围不写)

12.2.4 基础正则表达式字符

^word:

意义:待搜寻的字符串(word)在行首!

范例:搜寻行首为 # 开始的那一行,并列出行号

grep -n '^#' regular_express.txt

word$:

意义:待搜寻的字符串(word)在行尾!

范例:将行尾为 ! 的那一行打印出来,并列出行号

grep -n '!$' regular_express.txt

.:

意义:代表『一定有一个任意字符』的字符!

范例:搜寻的字符串可以是 (eve) (eae) (eee) (e e), 但不能仅有 (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] 是『非大写字符』的意思, 因为每一行均有非大写字符,例如第一行的 "Open Source" 就有 p,e,n,o.... 等等的小写字

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

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

\{n,m\}

意义:连续 n 到 m 个的『前一个 RE 字符』

意义:若为 \{n\} 则是连续 n 个的前一个 RE 字符,

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

12.2.5 sed工具

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

用法:

>sed [-nefr] [动作]

-n:使用安静(silent)模式,在一般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后面可以接字符串,而这些字符串会在新的一行下面出现(目前的下一行)

c:替换,c的后面可以接字符串,这些字符串可以替换n1和n2之间的行

d:删除,因为是删除,所以d后面通常不接任何参数

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

p:打印,也就是将某个选择的数据打印出来,通常p会与参数sed -n 一起使用

s:替换,可以直接进行替换的工作。通常这个s的动作可以搭配正则表达式!例如 1,20s/old/new/g

练习例子

以行为单位的新增/删除功能

例子:列出/etc/passwd 内容并打印行号,同时将2-5行删除

>nl /etc/passwd |sed '2,5d'

如果要删除第3行到最后一行呢,'3,$d',这个$代表最后一行的意思

例子:在第二行后(即第三行)加上‘drink tea’

>nl /etc/passwd |sed '2a drink tea'

以行为单位的替换与显示功能

例子:将2-5行替换为 "no 2-5 number"

>nl /etc/passwd |sed '2-5c no 2-5number'

例子:显示 5-7行的内容,前面讲的”head -n 7 |tail -n 5" ,现在使用sed

>nl /etc/passwd | sed -n '5,7p'

部分数据查找并替换功能

sed还可以 以行为单位的查找可替换功能,sed的查找替换和vi的非常相似:

sed 's/查找的内容/替换的内容/g'

直接修改文件内容(危险操作)

-i参数就可以直接修改文件。这个功能非常有帮助。

例如,你有一个100万行文件,你要在第100行加上文件,用vim可能会疯掉!因为文件太大了。可以利用sed功能。

12.3 扩展正则表达式

一般用户掌握基础正则就可以了。

grep 默认支持基础正则表达。可以grep -E 来支持扩展表达式,建议使用egrep命令

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

范例:查找god good goood等字符串,那么o+ 就代表一个即以上的字符

>egrep -n 'go+d' acd.txt

?:零个或者多个前一个RE字符

|:用或的方式找出数个字符串

范例:找god或good

>egrep -n 'god|good' abb.txt

():找出组字符串。

范例:我们要查找good 和glad 这两个字符,gd是重复的,我们就可以将ld和oo列到()中,然后用 ”|“ 分割 

>egrep -n 'g(ld|oo)d' ee.txt

()+:多个重复组

范例:查找A开头,C结尾。中间至少含有一个xyz

>egrep -n 'A(abc)+C' ab.txt

12.4 文件的格式化与相关处理

12.4.1 格式化打印:printf

语法:

>printf '打印格式' 实际内容

格式参数:

\a:警告声音输出

\b:退格键(backspace)

\f:清除屏幕

\n:输出新的一行

\r:即enter按键

\t:水平制表符[Tab]

\v:垂直制表符

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

关于C语言内常见的变量格式:

%ns:n是数字,代表多少个字符

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

%N.nf:nN都是整数,f代表float,N为共N位数其中n位为小数

12.4.2 awk :好用的数据处理工具

awk也是非常好的数据处理工具,相比sed常常用于整行处理,awk更倾向于将一行分解为数个字段来处理。

12.4.3文件比较工具

diff

语法:

>diff [-bBi] from-file to-file

from-file:一个文件名,作为欲比较的文件名

to-file:一个文件名,作为目标比较文件的文件名

注意:from-file 和to-file可用 - 替换,那个- 代表 standart input 意思

-b:忽略一行当中仅有多个空白的区别,例如“about    me” 与“about me”视为相同

-B:忽略空白行的区别

-i:忽略大小写的不同

cmp

cmp也是比较两个文件,他主要是以字节为单位进行比较,(diff是以行为单位进行比较)。

语法:

>cmp [-s] file1 file2

-s:将所有不同的字节处都列出来,默认仅会输出第一不同的地方。

patch

patch与diff有密不可分的关系。diff比较生成补丁文件,跟新旧版本文件。

12.4.4文件打印准备:pt
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: