声明:本文章为《鸟哥的Linux私房菜》读书摘要!



正规表示法

正规表示法(Regular Expression, RE,或称为常规表示法)是透过一些特殊字符的排列,用以『搜寻/取代/删除』一列或多列文字字符串, 简单的说,正规表示法就是用在字符串的处理上面的一项『表示式』。正规表示法就是处理字符串的方法,他是以行为单位来进行字符串的处理行为, 正规表示法透过一些特殊符号的辅助,可以让使用者轻易的达到『搜寻/删除/取代』某特定字符串的处理程序!

正规表示法的字符串表示方式依照不同的严谨度而分为: 基础正规表示法与延伸正规表示法。延伸型正规表示法除了简单的一组字符串处理之外,还可以作群组的字符串处理, 例如进行搜寻VBird或netman或lman的搜寻,注意,是『或(or)』而不是『和(and)』的处理, 此时就需要延伸正规表示法的帮助。

正规表示法与通配符是完全不一样的东西!通配符(wildcard)代表的是bash操作接口的一个功能』,但正规表示法则是一种字符串处理的表示方式。

基础正规表达法

语系对正规表示法的影响
    文件其实记录的仅有 0与1,我们看到的字符文字与数字都是透过编码表转换来的。由于不同语系的编码数据并不相同,所以就会造成数据撷取结果的差异了。 举例来说,在英文大小写的编码顺序中,zh_TW.big5及C 这两种语系的输出结果分别如下:
LANG=C 时:0 1 2 3 4 ... A B C D ... Z a b c d ...z
LANG=zh_TW 时:0 1 2 3 4 ... a A b B c C d D ... z Z

所以使用正规表示法时,需要特别留意当时环境的语系为何

由于一般我们在练习正规表示法时,使用的是兼容于POSIX的标准,因此就使用『C』这个语系。

有些特殊符号需要我们记忆

grep的一些进阶选项

grep 在数据中查寻一个字符串时,是以 " 整行 " 为单位来进行数据的撷取的! 』也就是说,假如一个文件内有 10 行,其中有两行具有你所搜寻的字符串,则将那两行显示在屏幕上,其他的就丢弃了!

基础正规表示法练习 

练习前的设置
语系已经使用『export LANG=C; export LC_ALL=C』的设定值;
grep 已经使用 alias 设定成为『grep --color=auto』
例题一、搜寻特定字符串

反向选择:也就是说,当该行没有'the'这个字符串时才显示在屏幕上

如果你想要取得不论大小写的the这个字符串

例题二、利用中括号[]来搜寻集合字符
如果我想要搜寻 test 或taste这两个单字时,可以发现到,其实她们有共通的't?st'存在

其实[]里面不论有几个字符,他都仅代表某『一个』字符, 所以,上面的例子说明了,我需要的字符串是『tast』或『test』两个字符串而已
如果想要搜寻到有 oo 的字符时

但是,如果我不想要oo前面有g的话

再来,假设我oo前面不想要有小写字符,所以,我可以这样写[^abcd....z]oo ,由于小写字符的ASCII上编码的顺序是连续的,也可以这样写 [^a-z]oo

由于考虑到语系对于编码顺序的影响,因此除了连续编码使用减号『-』之外, 你也可以使用如下的方法

例题三、行首与行尾字符^ $

我们在例题一当中,可以查询到一行字符串里面有the的,那如果我想要让the只在行首列出 ,则需要制表符。

如果我想要开头是小写字符的那一行就列出

那个^符号,在字符集合符号(括号[])之内与之外是不同的! 在[]内代表『反向选择』,在 [] 之外则代表定位在行首的意义

那如果我想要找出来,行尾结束为小数点(.)的那一行

特别注意到,因为小数点具有其他意义(底下会介绍),所以必须要使用跳脱字符(\)来加以解除其特殊意义
不过,你或许会觉得奇怪,但是第 5~9 行最后面也是 . 啊~怎么无法打印出来? 这里就牵涉到Windows平台的软件对于断行字符的判断问题了!我们使用cat -A将第五行拿出来看, 你会发现:

在Linux与Windows上的差异, 在上面的表格中我们可以发现5~9行为Windows的断行字符 (^M$) ,而正常的Linux应该仅有第10 行显示的那样($)。所以那个.自然就不是紧接在$之前喽。

如果我想要找出来,哪一行是『空白行』, 也就是说,该行并没有输入任何数据

不要空白行,不要#开头的注释行

例题四、任意一个字符.与重复字符*
我们知道通配符*可以用来代表任意(0或多个)字符, 但是正规表示法并不是通配符,两者之间是不相同的
 . (小数点):代表『一定有一个任意字符』的意思;
* (星星号):代表『重复前一个字符,0到无穷多次』的意思,为组合形态;

假设我需要找出g??d的字符串,亦即共有四个字符, 起头是g而结束是d

* 代表的是『 重复0个或多个前面的RE字符』的意义, 因此,『o*』代表的是:『拥有空字符或一个o以上的字符』
当我们需要『至少两个 o 以上的字符串』时,就需要ooo*

如果我想要字符串开头与结尾都是g,但是两个g之间仅能存在至少一个o ,亦即是 gog, goog, gooog....等等

.*就代表零个或多个任意字符

例题五、限定连续 RE 字符范围 {}
我想要找出两个到五个 o 的连续字符串,该如何作?这时候就得要使用到限定范围的字符{}了。 但因为{与}的符号在shell是有特殊意义的,因此, 我们必须要使用跳脱字符\来让他失去特殊意义才行。

我们要找出g后面接2到5个o,然后再接一个g 的字符串

如果我想要的是2个
o 以上的 goooo....g呢?除了可以是gooo*g,也可以是go\{2,\}g

基础正规表示法字符汇整 (characters)


sed工具

sed本身也是一个管线命令,可以分析standard input的。sed还可以将数据进行取代、删除、新增、撷取特定行等等的功能

下面来看看具体的应用例程。

如果题型变化一下,举例来说,如果只要删除第2行,可以使用『nl /etc/passwd | sed '2d'』来达成,至于若是要删除第3 到最后一行,则是『nl /etc/passwd | sed '3,$d'』的啦,那个钱字号『$』代表最后一行!

这个范例的重点是『我们可以新增不只一行喔!可以新增好几行』但是每一行之间都必须要以反斜杠『\』来进行新行的增加喔!所以,上面的例子中,我们可以发现在第一行的最后面就有\存在。

我们以前想要列出第11~20 行, 得要透过『head -n 20 | tail -n 10』之类的方法来处理,很麻烦啦~sed则可以简单的直接取出你想要的那几行。

除了整行的处理模式之外,sed 还可以用行为单位进行部分数据的搜寻并取代的功能喔! 基本上sed的搜寻与取代的与vi 相当的类似(注意与c功能的不同用法)

使用底下这个取得IP数据的范例,一段一段的来处理给您瞧瞧,让你了解一下什么是咱们所谓的搜寻并取代

假设我只要MAN存在的那几行数据, 但是含有# 在内的批注我不想要,而且空白行我也不要

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

sed的『-i』选项可以直接修改文件内容,这功能非常有帮助!举例来说,如果你有一个100万行的文件,你要在第 100 行加某些文字,此时使用 vim可能会疯掉!因为文件太大了!那怎办?就利用sed啊!透过 sed直接修改/取代的功能,你甚至不需要使用vim去修订。


延伸正规表示法
在上节的例题三的最后一个例子中,我们要去除空白行与行首为#的行列,使用的是
grep -v '^$' regular_express.txt | grep -v '^#'
需要使用到管线命令来搜寻两次!那么如果使用延伸型的正规表示法,我们可以简化为:
egrep -v '^$|^#' regular_express.txt
延伸型正规表示法可以透过群组功能『|』来进行一次搜寻!那个在单引号内的管线意义为『或 or』啦! 是否变的更简单呢?此外,grep预设仅支持基础正规表示法,如果要使用延伸型正规表示法,你可以使用grep -E, 不过更建议直接使用egrep!直接区分指令比较好记忆!其实egrep与 grep -E是类似命令别名的关系

文件的格式化与相关处理

格式化打印: printf

printf.txt文件

我们将每个数据都以[tab]作为分隔,但是由于 Chinese长度太长,导致 English中间多了一个 [tab] 来将资料排列整齐
在 printf 后续的那一段格式中,%s代表一个不固定长度的字符串,而字符串与字符串中间就以\t这个 [tab]分隔符来处理!你要记得的是,由于\t与 %s中间还有空格,因此每个字符串间会有一个[tab]与一个空格键的分隔 。

%10s代表的是一个长度为10个字符的字符串字段, %5i 代表的是长度为 5个字符的数字字段,至于那个%8.2f则代表长度为 8 个字符的具有小数点的字段,其中小数点有两个字符宽度。我们可以使用底下的说明来介绍%8.2f的意义:
字符宽度: 12345678
%8.2f 意义: 00000.00

awk:好用的数据处理工具

awk 也是一个非常棒的数据处理工具!相较于sed 常常作用于一整个行的处理,awk 则比较倾向于一行当中分成数个『字段』来处理

awk可以处理后续接
的文件,也可以读取来自前个指令的 standard output 。 但如前面说的,awk主要是处理『每一行
的字段内的数据』,而默认的『字段的分隔符为 "空格键"或"[tab]键"』!举例来说,我们用last 可
以将登入者的数据取出来,结果如下所示:

若我想要取出账号与登入者的IP,且账号与 IP之间以[tab] 隔开,则会变成这样:

上表是awk最常使用的动作!透过 print 的功能将字段数据列出来!字段的分隔则以空格键或[tab]按键来隔开。

在awk 的括号内, 每一行的每个字段都是有变量名称的,那就是 $1, $2...等变量名称。以上面的例子来说,dmtsai 是 $1,因为他是第一栏嘛!至于 192.168.1.100是第三栏, 所以他就是$3 啦

整个awk 的处理流程是:
1. 读入第一行,并将第一行的资料填入$0, $1, $2.... 等变数当中;
2. 依据"条件类型"的限制,判断是否需要进行后面的 "动作";
3. 做完所有的动作与条件类型;
4. 若还有后续的『行』的数据,则重复上面1~3 的步骤,直到所有的数据都读完为止。

经过这样的步骤,你会晓得, awk 是『 以行为一次处理的单位』, 而『以字段为最小的处理单位』。好了,那么awk 怎么知道我到底这个数据有几行?有几栏呢?这就需要awk 的内建变量的帮忙啦~

我们继续以上面last -n 5 的例子来做说明,如果我想要:
 列出每一行的账号(就是$1);
 列出目前处理的行数(就是awk 内的 NR变量)
 并且说明,该行有多少字段(就是awk 内的 NF变量)
则可以这样:

awk的逻辑运算字符

在 /etc/passwd 当中是以冒号":" 来作为字段的分隔, 该文件中第一字段为账号,第三字段则是UID。那假设我要查阅,第三栏小于10 以下的数据,并且仅列出账号与第三栏, 那么可以这样做:

有趣吧!不过,怎么第一行没有正确的显示出来呢?这是因为我们读入第一行的时候,那些变数$1,$2... 默认还是以空格键为分隔的,所以虽然我们定义了FS=":" 了, 但是却仅能在第二行后才开始生效。那么怎么办呢?我们可以预先设定awk 的变量啊! 利用 BEGIN 这个关键词

awk的指令间隔:所有 awk 的动作,亦即在 {} 内的动作,如果有需要多个指令辅助时,可利用分号『;』
间隔, 或者直接以 [Enter] 按键来隔开每个指令,例如上面的范例中,鸟哥共按了三次[enter] 喔!
逻辑运算当中,如果是『等于』的情况,则务必使用两个等号『 ==』!
格式化输出时,在 printf 的格式设定当中,务必加上 \n ,才能进行分行!
与 bash shell 的变量不同,在 awk 当中,变量可以直接使用,不需加上$ 符号。

文件比对工具 

同一个软件包的不同版本之间,比较配置文件与原始档的差异』。 很多时候所谓的文件比对,通常是用在ASCII 纯文本档的比对上的。常用的文件对比指令有diff、cmp和patch
diff就是用在比对两个文件之间的差异的,并且是以行为单位来比对的!一般是用在 ASCII纯文本档的比对上。 由于是以行为比对的单位,因此 diff通常是用在同一的文件(或软件)的新旧版本差异上 
假如我们要将/etc/passwd 处理成为一个新的版本,处理方式为: 将第四行删除,第六行则取代成为『no six line』,新的文件放置到/tmp/test 里面,那么应该怎么做
 

接下来讨论一下关于diff 的用法

cmp主要也是在比对两个文件,他主要利用『字节』单位去比对, 因此,当然也可以比对 binary file啰~(还是要再提醒喔,diff 主要是以『行』为单位比对,cmp 则是以『字节』为单位去比对,这并不相同!

patch这个指令与 diff 可是有密不可分的关系啊!我们前面提到, diff可以用来分辨两个版本之间的差异, 举例来说,刚刚我们所建立的 passwd.old及 passwd.new 之间就是两个不同版本的文件。 那么,如果要『升级』呢?就是『 将旧的文件升级成为新的文件』时,应该要怎么做呢? 其实也不难啦!就是『先比较先旧版本的差异,并将差异档制作成为补丁档,再由补丁档更新旧文件』即可。

一般来说,使用diff 制作出来的比较文件通常使用扩展名为.patch 啰。至于内容就如同上面介绍的样子。 基本上就是以行为单位,看看哪边有一样与不一样的,找到一样的地方,然后将不一样的地方取代掉! 以上面表格为例,新文件看到- 会删除,看到 +会加入!好了,那么如何将旧的文件更新成为新的内容呢? 就是将 passwd.old改成与 passwd.new 相同!可以这样做:

文件打印准备:pr

linux读书摘要--正规表示法与文件格式化处理相关推荐

  1. Linux之旅 9:正则表达式与文件格式化

    Linux之旅 9:正则表达式与文件格式化 (图片来自常用正则表达式) 什么是正则表达式 正则表达式(简称为正则)可以看做是一种微型标记语言,通过定义一系列符号来灵活地设定一种匹配模式,对目标字符串进 ...

  2. linux下的orre命令,鸟哥的 Linux 私房菜 -- 正规表示法 (regular expression, RE) 与文件格式化处理...

    要了解正规表示法最简单的方法就是由实际练习去感受啦!所以在汇整正规表示法特殊符号前, 我们先以底下这个文件的内容来进行正规表示法的理解吧!先说明一下,底下的练习大前提是: 语系已经使用『 export ...

  3. 8.Linux的正规表达式与文件格式化处理

    目录 1.什么是正规表达式? 2.基础正规表达式 2.1.grep的一些进阶阶选项 3.sed工具 4.awk:好用的数据处理工具 5.diff工具:查看档案的差异 1.什么是正规表达式? 正规表示法 ...

  4. Linux的简单shell脚本中修改文件操作

    Linux的简单shell脚本中修改文件操作 Linux Shell常用技巧(三) sed 八.流编辑器sed 8.1 sed简介 sed是stream editor的缩写,一种流编辑器,它一次处理一 ...

  5. Linux读书笔记2

    1. vi 文字处理器 vi 共分为三种模式,分别是『一般模式』. 『编辑模式』与『指令列命令模式』 使用 vi 建立一个档名为 test.txt 的资料 [root@linux ~]# vi tes ...

  6. 基础正规表示法字符汇整 (characters)

    再次强调:『正规表示法的特殊字节』与一般在命令列输入命令的『万用字节』并不相同, 例如,在万用字节当中的 * 代表的是『 0 ~ 无限多个字节』的意思,但是在正规表示法当中, * 则是『重复 0 到无 ...

  7. linux文件系统添加pcm,linux下用sox批量将pcm文件加wav头、批量修改采样率、切音频...

    linux下用sox可以给pcm文件加头 例如:test.pcm是不带wav头的pcm文件 $ sox -t raw -c 1 -e signed-integer -b 16 -r 16000 tes ...

  8. 【转】Linux的.a、.so和.o文件

    转自:Linux的.a..so和.o文件_chlele0105的专栏-CSDN博客 在说明Linux的.a..so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系 wi ...

  9. 在Linux上使用logwatch分析监控日志文件

    原文:http://seanlook.com/2014/08/23/linux-logwatch-usage/ 1. 介绍 在维护Linux服务器时,经常需要查看系统中各种服务的日志,以检查服务器的运 ...

最新文章

  1. ATM(BZOJ 1179)
  2. rtos与linux软件开发,实时Linux和RTOS的基本特性及技术进行比较
  3. 校宝在线携手神策数据 数据赋能产品服务体验双升级
  4. html隐藏块元素过度动画,CSS3实现DIV图层隐藏到显示的过渡效果
  5. JDK源码解析之 Java.lang.Byte
  6. 借百度数据,建立你自己的程序
  7. 关于字符串和字节编码的问题(转)
  8. 数学计算机学具制作,神奇的数学
  9. 如何将Excel表格随机打乱顺序
  10. 中科矿业带你走进SWARM/BZZ,选择去或留?
  11. 怎么用手机连接电脑上网听语音
  12. linux运行搜狗拼音,搜狗输入法 for Linux版的安装图文教程
  13. 《关键对话》思维导图
  14. 自动驾驶汽车是如何利用高精度地图和高精度定位来进行“导航”的
  15. 信创只是开始_《作业帮高管团队亲笔信:D轮只是开始,一切归零,重新出发》...
  16. smart夏季的笑话
  17. android 获取sn序列号
  18. 餐饮行业最新的经营模式——私域运营案例
  19. 分享百度文库推广技巧分享
  20. 中山大学计算机在职研究生分数线,报考中山大学在职研究生考多少分算及格?...

热门文章

  1. 视频通话和直播技术webRTC和RTMP探究
  2. 使用D2RQ转换关系型数据库Mysql数据为RDF
  3. uniapp微信小程序打电话
  4. 蘑菇街 App 的组件化之路
  5. 第六章(项目进度管理)知识点
  6. 使用微信小程序editor富文本编辑器(爬坑要点)
  7. Unknown Faceted Project Problem (Java Version Mismatch)
  8. 删除pdf签名 acrobat
  9. Java求一元二次方程的根
  10. 拼多多Temu出海项目正式上线,教你如何做好测评补单,分得第一杯羹