目录
这篇的前一篇:正则表达式与文件格式化处理(2)-sed工具(主)
延伸正则表达式
事实上,一般读者只要了解基础型的正则表达式大概就已经相当足够了,不过,某些时刻为了要简化整个指令操作,了解一下使用范围更广的延伸型正则表达式的表示式会更方便呢!举个简单的例子好了,在上节的例题三的最后一个例子中,我们要去除空白行与行首为 # 的行列,使用的是
grep -v '^$' regular_express.txt | grep -v '^#'
需要使用到管线命令来搜寻两次!那么如果使用延伸型的正则表达式,我们可以简化为:
egrep -v '^$|^#' regular_express.txt
由于下面的范例还是有使用到 regular_express.txt 可以重新下载.
wget http://linux.vbird.org/linux_basic/0330regularex/regular_express.txt
正则表达式之后,到这个延伸型的正则表达式,你应该也会想到,也就是多几个重要的特殊符号.
+ | 意义:重复 “ 一个或一个以上 ” 的前一个 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' 上面的例子意思是说,我要找开头是 A 结尾是 C ,中间有一个以上的 "xyz" 字串的意思. |
文件的格式化与相关处理
接下来让我们来将文件进行一些简单的编排吧!下面这些动作可以将你的讯息进行排版的动作,
不需要重新以 vim 去编辑,通过数据流重导向配合下面介绍的 printf 功能,以及 awk 指令,
就可以让你的讯息以你想要的模样来输出了!试看看吧!
举例来说,考试卷分数的输出,姓名与科目及分数之间,总是可以稍微作
个比较漂亮的版面配置吧? 例如我想要输出下面的样式:
Name Chinese English Math Average
DmTsai 80 60 92 77.33
VBird 75 55 80 70.00
Ken 60 90 70 73.33
上表的数据主要分成五个字段,各个字段之间可使用 tab 或空白键进行分隔.
请将上表的数据转存成为 printf.txt 文件名,等一下我们会
利用这个文件来进行几个小练习的。 因为每个字段的原始数据长度其实并非是如此固定的
( Chinese 长度就是比 Name 要多), 而我就是想要如此表示出这些数据,此时,
就得需要打印格式管理员 printf 的帮忙了! printf 可以帮我们将数据输出的结果格式化,
而且而支持一些特殊的字符~下面我们就来看看!
[dmtsai@study ~]$ printf '打印格式' 实际内容
选项与参数:
关于格式方面的几个特殊样式:
\a 警告声音输出
\b 倒退键(backspace)
\f 清除屏幕 (form feed)
\n 输出新的一行
\r 亦即 Enter 按键
\t 水平的 [tab] 按键
\v 垂直的 [tab] 按键
\xNN NN 为两位数的数字,可以转换数字成为字符。
关于 C 程序语言内,常见的变量格式
%ns 那个 n 是数字, s 代表 string ,亦即多少个字符;
%ni 那个 n 是数字, i 代表 integer ,亦即多少整数码数;
%N.nf 那个 n 与 N 都是数字, f 代表 floating (浮点),如果有小数码数,
假设我共要十个位数,但小数点有两位,即为 %10.2f 啰!
范例一:将刚刚上头数据的文件 ( printf.txt ) 内容仅列出姓名与成绩:(用 [tab] 分隔)
printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt)
由于 printf 并不是管线命令,因此我们得要通过类似上面的功能,将文件内容先提出来给 printf 作为后续的数据才行。 如上所示,我们
将每个数据都以 [tab] 作为分隔,但是由于 Chinese 长度太长,导致 English 中间多了一个 [tab] 来将数据排列整齐!啊~结果就看到数据对齐
结果的差异了!
另外,在 printf 后续的那一段格式中, %s 代表一个不固定长度的字串,而字串与字串中间就以 \t 这个 [tab] 分隔符号来处理!你要记得
的是,由于 \t 与 %s 中间还有空格,因此每个字串间会有一个 [tab] 与一个空白键的分隔喔!
既然每个字段的长度不固定会造成上述的困扰,那我将每个字段固定就好啦!没错没错!这样想非常好! 所以我们就将数据给他进行固
定字段长度的设计吧!
范例二:将上述数据关于第二行以后,分别以字串、整数、小数点来显示:
printf '%10s %5i %5i %5i %8.2f \n' $ ( cat printf.txt | grep -v Name )
上面这一串格式想必您看得很辛苦!没关系!一个一个来解释!上面的格式共分为五个字段, %10s 代表的是一个长度为 10 个字符的
字串字段, %5i 代表的是长度为 5 个字符的数字字段,至于那个 %8.2f 则代表长度为 8 个字符的具有小数点的字段,其中小数点有两个字符宽
度。我们可以使用下面的说明来介绍 %8.2f 的意义:
如上所述,全部的宽度仅有 8 个字符,整数部分占有 5 个字符,小数点本身 ( . ) 占一位,小数点下的位数则有两位。 这种格式经常使
用于数值程序的设计中!这样了解乎?自己试看看如果要将小数点位数变成 1 位又该如何处理?
printf 除了可以格式化处理之外,他还可以依据 ASCII 的数字与图形对应来显示数据喔 [3] ! 举例来说 16 进位的 45 可以得到什么 ASCII
的显示图 (其实是字符啦)?
范例三:列出 16 进位数值 45 代表的字符为何?
printf '\x45\n'
awk :好用的数据处理工具
awk 也是一个非常棒的数据处理工具!相较于 sed 常常作用于一整个行的处理, awk 则比较倾向于一行当中分成数个 “ 字段 ” 来处理。
因此, awk 相当的适合处理小型的数据数据处理呢! awk 通常运行的模式是这样的:
awk ' 条件类型 1{ 动作 1} 条件类型 2{ 动作 2} ...' filename