正则表达式
符号
含义
.
匹配任意ASCII中任意单个字符,或是字母,或是数字
^
匹配行首
$
匹配行尾
*
匹配任意字符或前一个的一次或多次重复
\
转义,被转义的有$ . ‘ “ * [ ] ^ \ ( ) | + ?
[…] [-]
匹配一个范围或集合
\{\}
匹配n次:\{n\},最少n次:\{n,\},m到n次:\{m,n\},
+
仅用于awk,标识匹配一个或多个
?
仅用于awk,匹配0次或1次
grep
先给出示例文件data.f的内容
48 Dec 3BC1977 LPSX 68.00 LVX2A 138
483 Sept 5AP1996 USP 65.00 LVX2C 189
47 Oct 3ZL1998 LPSX 43.00 KVM9D 512
219 dec 2CC1999 CAD 23.00 PLV2C 68
484 nov 7PL1996 CAD 49.00 PLV2C 234
483 may 5PA1998 USP 37.00 KVM9D 644
216 sept 3ZL1998 USP 86.00 KVM9E 234
grep一般匹配
一般匹配通常需要将匹配的模式使用双引号括起来。
grep的一般格式为:grep [选项] 基本正则表达式 [文件]
注意对输入的参数字符串使用双引号
grep的选项:
-c 只输出匹配行的数量
-i 不区分大小写(只适用于单字符)
-h 查询多文件时,不显示文件名
-l 查询多文件时,只输出包含匹配字符的文件名
-n 显示匹配行的行号
-s 不显示不存在或无匹配文本的错误信息
-v 显示不包含匹配文本的所有行
查询多个文件:可以使用文件占位符查询多个文件,也可以将多个文件列出,如:
grep "45" data*.f
grep "45" data1.f data2.f
全字匹配:在匹配的字符后边加上\>
grep "45\>" data.f
grep使用正则匹配
为了防止shell的替换等其他行为发生,使用时通常使用单引号。
模式范围:grep ‘48[43]‘ data.f,匹配484/483
不匹配行首:grep ‘^[^48]‘ data.f
先匹配月份,再匹配模式:grep ‘[Ss]ept‘ data.f | grep 443
空行:grep ‘^$‘ data.f
扩展模式:
使用-E参数,这一扩展允许使用扩展模式匹配
匹配219或者216:grep -E ‘219|216‘ data.f
类名
类名
等价的正则
类名
等价的正则
[[:upper:]]
[A-Z]
[[:alnum:]]
[0-9a-zA-Z]
[[:lower:]]
[a-z]
[[:space:]]
空格或tab键
[[:digit:]]
[0-9]
[[:alpha:]]
[a-zA-Z]
grep ‘[[:alpha:]]*‘ data.f
系统grep命令
目录:ls -l grep ‘^d‘
passwd文件:grep "angel" /etc/passed
查看DNS服务进程(通常为named):ps | grep "named"
egrep
expression或extended grep,接受所有的正则表达式,特点为:
文件作为查询的正则字符串。egrep -f grepstrings data.f
使用 | 符号,表示匹配两边之一
使用 ^ 符号,表示不匹配到。
AWK进行文本过滤
Usage: awk [POSIX or GNU style options] -f progfile file ...
Usage: awk [POSIX or GNU style options] ‘program‘ file ...
其中progfile中或者‘program‘是真正的AWK命令,最后的file是输入文件(s)。
常用的参数是-F field-separator,指定文件分隔符,默认为空白字符。对于passed之类的使用冒号分割的,则使用-F:参数,表示冒号为列分割。
同样可以使得同sh脚本一样,在首行指定#/bin/awk,可以使脚本文件使用AWK进行执行。
awk脚本
awk脚本由各种操作和模式组成。
awk将每次读取一行,然后使用分隔符将每一行分割成多个域。
awk语句都由模式和动作组成,模式决定动作的触发条件,如果省略模式部分,动作将时刻保持执行。
awk模式,包括两个特殊字段,BEGIN和END。BEGIN使用在浏览文本动作前,之后文本浏览动作开始执行。END使用在浏览文本动作之后,打印输出文本总数和结尾状态标识。如不特殊指明,总是匹配或打印行数。
awk动作,在大括号{}内指明,多数用来打印,还有诸如if和循环语句等。如不特殊指明,将打印所有浏览出来的记录。
域:awk执行动作时,将域标记为$1 $2 $3 ...,其中$0标识所有域。
记录:每一行就是一个记录
提取文件中的每一列
awk ‘{print $0}‘ data.f
awk ‘{print $3}‘ data.f
添加文件头尾
awk ‘BEGIN {print "Month\tPrice\n------------------------"} {print $2"\t"$5} END {print "------------------\ntip: end of file"}‘ data.f
awk中的正则表达式
awk中使用正则时,是使用//括起来。如:/wang*/
条件操作符
操作符
描述
操作符
描述
<
小于
>=
大于等于
<=
小于等于
~
匹配正则表达式
==
等于
!~
不匹配正则表达式
!=
不等于
&&
且
||
或
!
非
打印符合条件的行的部分列: awk ‘{if($4~/LPSX/) print $2"\t"$4"\t"$5}‘ data.f
打印不符合条件的行的部分列: awk ‘{if($4!~/LPSX/) print $2"\t"$4"\t"$5}‘ data.f
打印第一列小于第七列的:awk ‘{if($1 < $7) print $1"\t"$4"\t"$7}‘ data.f
awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行-F选项
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
打印记录号,域个数,最后打印文件名称
awk ‘{print NF"\t"NR"\t"$0} END {print FILENAME}‘ data.f
awk操作符
赋值操作:=、+=、*=、/=、%=、^=
条件表达式:?
或且非:||、&&、!
匹配:~、!~
关系:、>=、!=、==
算术:+、-、*、/、%、^
前后缀:++、--
使用变量:awk ‘{name=$4; price=$5;print name"\t"price} ‘ data.f
内置字符串函数
gsub(r,s)
在整个$0中用s替代r
gsub(r,s,t)
在整个t中用s替代r
index(s,t)
返回s中字符串t的第一位置
length(s)
返回s长度
match(s,r)
测试s是否包含匹配r的字符串
split(s,a,fs)
在fs上将s分成序列a
sprint(fmt,exp)
返回经fmt格式化后的exp
sub(r,s)
用$0中最左边最长的子串代替s
substr(s,p)
返回字符串s中从p开始的后缀部分
substr(s,p,n)
返回字符串s中从p开始长度为n的后缀部分
返回每行的长度:awk ‘{print $0"\t"length($0)} ‘ data.f
awk使用printf修饰输出格式
修饰符
含义
-
左对齐
Width
域的步长,用0表示0步长
.prec
最大字符串长度,或小数点右边的位数
%c
ASCII字符
%d
整数
%e
浮点数,科学记数法
%f
浮点数,例如(123.44)
%g
awk决定使用哪种浮点数转换e或者f
%o
八进制数
注意printf不会自动输出换行。
对ASCII的65输出字符A:awk ‘BEGIN {printf "%c\n",65}‘
固定列宽输出:awk ‘{printf "%-15s %s\n",$1,$3}‘ data.f
awk脚本文件
如下是一个脚本文件
第一行表示执行脚本的命令和参数,!/bin/awk -f
执行时,键入脚本名称和输入文件即可得到输出
awk数组
使用实例:
将文本划分到数组:awk ‘BEGIN {print split("123:456:789",array,":")}‘
得到的数组为:array[1]="123"等。
循环:For (element in array) print array[element]