正则表达式
- 正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念
- 正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本,许多程序设计语言都支持利用正则表达式进行字符串操作,例如,在Perl中就内建了一个功能强大的正则表达式引擎
- 正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的
- 正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen
- 正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑
- 正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串
grep
-a 或 --text | 不要忽略二进制的数据。 |
-A<显示行数> 或 --after-context=<显示行数> | 除了显示符合范本样式的那一列之外,并显示该行之后的内容。 |
-b 或 --byte-offset | 在显示符合样式的那一行之前,标示出该行第一个字符的编号。 |
-B<显示行数> 或 --before-context=<显示行数> | 除了显示符合样式的那一行之外,并显示该行之前的内容。 |
-c 或 --count | 计算符合样式的列数。 |
-C<显示行数> 或 --context=<显示行数>或-<显示行数> | 除了显示符合样式的那一行之外,并显示该行之前后的内容。 |
-d <动作> 或 --directories=<动作> | 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。 |
-e<范本样式> 或 --regexp=<范本样式> | 指定字符串做为查找文件内容的样式。 |
-E 或 --extended-regexp | 将样式为延伸的正则表达式来使用。 |
-f<规则文件> 或 --file=<规则文件> | 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。 |
-F 或 --fixed-regexp | 将样式视为固定字符串的列表。 |
-G 或 --basic-regexp | 将样式视为普通的表示法来使用。 |
-h 或 --no-filename | 在显示符合样式的那一行之前,不标示该行所属的文件名称。 |
-H 或 --with-filename | 在显示符合样式的那一行之前,表示该行所属的文件名称。 |
-i 或 --ignore-case | 忽略字符大小写的差别。 |
-l 或 --file-with-matches | 列出文件内容符合指定的样式的文件名称。 |
-L 或 --files-without-match | 列出文件内容不符合指定的样式的文件名称。 |
-n 或 --line-number | 在显示符合样式的那一行之前,标示出该行的列数编号。 |
-o 或 --only-matching | 只显示匹配PATTERN 部分。 |
-q 或 --quiet或–silent | 不显示任何信息。 |
-r 或 --recursive | 此参数的效果和指定"-d recurse"参数相同。 |
-s 或 --no-messages | 不显示错误信息。 |
-v 或 --revert-match | 显示不包含匹配文本的所有行。 |
-V 或 --version | 显示版本信息。 |
-w 或 --word-regexp | 只显示全字符合的列。 |
-x --line-regexp | 只显示全列符合的列。 |
-y | 此参数的效果和指定"-i"参数相同。 |
–color=auto | 关键字部分显示颜色 |
其实 [] 里面不论有几个字节,他都谨代表某一个字节
字符类的反向选择 [^] :如果想要搜索到有 oo 的行,但不想要 oo 前面有 g
grep -n '[^g]oo' regular_express.txt
行首与行尾字节 ^ $
^ 符号,在字符类符号(括号[])之内与之外是不同的! 在 [] 内代表『反向选择』,在 [] 之外则代表定位在行首的意义!
grep -n '^$' regular_express.txt #找出空白行
任意一个字节 . 与重复字节 *
这两个符号在正则表达式的意义如下:
. (小数点):代表『一定有一个任意字节』的意思;
* (星号):代表『重复前一个字符, 0 到无穷多次』的意思,为组合形态
限定连续 RE 字符范围 {}
我们可以利用 . 与 RE 字符及 * 来配置 0 个到无限多个重复字节, 那如果我想要限制一个范围区间内的重复字节数呢?
举例来说,我想要找出两个到五个 o 的连续字串,该如何作?这时候就得要使用到限定范围的字符 {} 了。
但因为 { 与 } 的符号在 shell 是有特殊意义的,因此, 我们必须要使用字符 \ 来让他失去特殊意义才行。
至於 {} 的语法是这样的,假设我要找到两个 o 的字串,可以是:
grep -n 'o\{2\}' regular_express.txt #使用扩展grep的主要好处是增加了额外的正则表达式元字符集。
grep root passwd | 搜索全文中的root |
grep ^root passwd | 搜索全文中以root开头的 |
grep root$ passwd | 搜索全文中以root结尾的 |
grep -i root passwd | 忽略大小写 |
grep -E “root/ROOT” passwd | 同时匹配多个条件 |
grep “root$” passwd -n | 过滤出以root结尾的,且排序 |
grep “root$” passwd -v | 过滤出以root结尾的,且排序 |
grep “root$” passwd -B1 | 过滤出以root结尾的行及其前一行 |
grep “root$” passwd -B1 | 过滤出以root结尾的行及其前一行 |
grep “root$” passwd -A1 | 过滤出以root结尾的行及其后一行 |
grep “root$” passwd -2 | 过滤出以root结尾的行及其前后2行 |
grep root passwd | 搜索全文中的root,grep属于贪婪模式的搜索和匹配,只要行中有root出现,它就会打印匹配的行 |
grep -Ei “root” passwd -i #表示忽略大小写过滤
grep -Ei “^root” passwd #过滤出以root开头的
grep -Ei “^root |root$” passwd #过滤出以root开头和结尾的
grep ROOT passwd #过滤出ROOT所在行,并显示行号
grep ROOT passwd -n2 #过滤出ROOT所在行及其上下2行,并显示行号
grep ROOT passwd -2 #过滤出ROOT所在行及其上下2行
grep ROOT passwd -B1 #过滤出ROOT所在行及其前一行
grep ROOT passwd -A1 #过滤出ROOT所在行及其后一行
grep -Ei "\<root" passwd #过滤出passwd文件里不以root结尾的行
^root | 打印以westos开头的行 |
root$ | 打印以westos结尾的行 |
‘w…s’ | 打印w和s中间包括四个字符的行 |
‘w…’ | 打印w开头,后面四个字符的行 |
‘…s’ | 打印s结尾,前面四个字符的行 |
几个点就可以匹配几个字符
*字符出现 | [0- 任意次 ] |
?字符出现 | [0-1 次 ] |
+字符出现 | [1- 任意次 ] |
{n}字符出现 | [n 次 ] |
{m,n} 字符出现 | [ 最少出现 m 次,最多出现 n 次 ] |
{0,n}字符出现 | [0-n 次 ] |
{m,}字符出现 | [ 至少 m 次 ] |
(xy){n}xy | 关键字出现 [n 次 ] |
.* | 关键字之间匹配任意字符 |
grep -E x{1}y aa #过滤x至少出现1次
egrep
egrep = grep -E 可以使用基本的正则表达外, 还可以用扩展表达式. 注意区别.
扩展表达式:
+ | 匹配一个或者多个先前的字符, 至少一个先前字符. |
? | 匹配0个或者多个先前字符. |
() | 字符组, 如: love(able |
(…)(…)\1\2 | 模板匹配. \1代表前面第一个模板, \2代第二个括弧里面的模板. |
x{m,n} =x{m,n} | x的字符数量在m到n个之间. |
egrep ‘^+’ file | 以一个或者多个空格开头的行. |
grep ‘^*’ file | 同上 |
egrep ‘(ab)+’ file | 包含至少一个ab的行. |
egrep ‘x[0-9]?’ file | 包含x或者x后面跟着0个或者多个数字的行. |
egrep ‘fun.$’ * | 所有文件里面以fun.结尾的行. |
egrep ‘[A-Z]+’ file | 至少包含一个大写字母的行. |
egrep ‘[0-9]’ file | 至少一个数字的行. |
egrep ‘[A-Z]…[0-9]’ file | 有五个字符, 第一个式大写, 最后一个是数字的行. |
egrep ‘[tT]est’ file | 包含单词test或Test的行. |
egrep ‘ken sun’ file | 包含ken sun的行. |
egrep -v ‘marry’ file | 不包含marry的行. |
egrep -i ‘sam’ file | 不考虑sam的大小写,含有sam的行. |
egrep -l “dear ken” * | 包含dear ken的所有文件的清单. |
egrep -n tom file | 包含tom的行, 每行前面追加行号. |
egrep -s “$name” file | 找到变量名$name的, 不打印而是显示退出状态. |
0表示找到. 1表示表达式没找到符合要求的, 2表示文件没找到. |
在正则下
\ | 关闭后续字符的特殊定义,但 {}会打开其特殊定义 |
. | 任何单个字符 |
* | 0个或多个 在它之前的单个字符单独出现时 在BRE中不具有任何意义(因为前面为空 就什么都没有) |
^ | 在BRE中 在表达式开头处具有意义在ERE中 任何位置都有意义 |
$ | 同上,只是他代表的是结尾处 |
[] | 匹配方括号内任一字符 |
- | 在这里的意思是连续 ex:1-9 1到9 |
^ | 代表非,在方括号表达式中,所有的meta字符都会失去特殊含义 |
元字符 描述
\ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配字符“n”。“\n”匹配一个换行符。序列“\”匹配“\”而“(”则匹配“(”。 |
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
{n,} | n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 |
? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o?”将匹配所有“o”。 |
. | 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(. |
x | y 匹配x或y。例如,“z |
[xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
[^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。 |
[a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。 |
[^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。 |
\B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。 |
\cx | 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。 |
\d | 匹配一个数字字符。等价于[0-9]。 |
\D | 匹配一个非数字字符。等价于[^0-9]。 |
\f | 匹配一个换页符。等价于\x0c和\cL。 |
\n | 匹配一个换行符。等价于\x0a和\cJ。 |
\r | 匹配一个回车符。等价于\x0d和\cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。等价于\x09和\cI。 |
\v | 匹配一个垂直制表符。等价于\x0b和\cK。 |
\w | 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。 |
\W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 |
\xn | 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。 |
\num | 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。 |
\n | 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。 |
\nm | 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。 |
\nml | 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。 |
\un | 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。 |
sed
SED是一项Linux指令,功能同awk类似,差别在于,sed简单,对列处理的功能要差一些,awk的功能复杂,对列处理的功能比较强,sed用来操作纯
ASCII 码的文本 处理时 , 把当前处理的行存储在临时缓冲区中 , 称为“模式空间” (pattern space)
,可以指定仅仅处理哪些行 sed 符合模式条件的处理,不符合条件的不予处理,处理完成之后把缓冲区的内容送往屏幕接着处理下一行 ,这样不断重复
, 直到文件末尾,原来的内容是在磁盘当中放着,现在用sed命令处理的时候将内容掉入内存的一个地方用户处理,这个处理空间也叫模式空间。
p模式 | |
---|---|
sed -n ‘/:/p’ fstab | 显示有:号的行 |
sed -n ‘/UUID$/p’ fstab | 显示UUID结尾的行 |
sed -n ‘/^UUID/p’ fstab | 显示UUID开头的行 |
sed -n ‘2,6p’ fstab | 显示第2行和第6行 |
sed -n ‘2,6!p’ fstab | 显示除了第2行和第6行的其余行 |
a模式 | |
---|---|
sed ‘/^bin/a \hello’ /etc/fstab | 在bin行添加hello |
sed '/^bin/a \hello\nranran '/etc/fstab | 在bin行添加 hello 换行westos |
不换行
d模式 | |
---|---|
sed ‘/^UUID/d’ /etc/fstab | 删除UUID开头的行并将其余行显示出来 |
sed ‘/^#/d’ /etc/fstab | 删除#开头的行并将其余行显示出来 |
sed ‘/^$/d’/etc/fstab | 删除空行并将其余行显示出来 |
sed ‘1,4d’/etc/fstab | 删除1和4行并将其余行显示出来 |
sed –n ‘/^UUID/!d’ /etc/fstab -n | 不显示模式空间,删除除了UUID开头的行并将UUID行显示出来 |
sed的其他用法 | |
---|---|
sed -n ‘/^UUID/=’ fstab | 显示UUID开头的行是第几行 |
sed -n -e ‘/^UUID/p’ -e ‘/^ UUID/=’ fstab | 显示UUID开头的行并标号 |
sed -e ‘s/brown/green/; s/dog/cat/’ data | 替换brown为green且替换dog为cat |
sed -f rulesfile file | 贵者 |
sed ‘s/^//#/’/etc/fstab | 替换所有/开头的列为# |
sed ‘s@^/@#@g’/etc/fstab | @也可为分隔符 |
sed ‘s///#/g/’/etc/fstab | 替换所有/为# |
sed ‘G’ data | |
sed ‘$!G’ data | |
“sed ‘=’ data sed ‘N; s/\n/ /’” | |
sed -n ‘$p’ data | 将开头为UUID的行写到westos文件里(-n不显示文本空间) |
将:换成@
将:换成#
将1和3行的:换成@
将开头为lp和htal之间的行:换成@
awk
awk处理机制:awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行做一些总结性质的工作,然后将结果展现给用户
在命令格式上分别体现如下
:BEGIN{}:读入第一行文本之前执行,一般用来初始化操作;{}:逐行处理,逐行读入文本执行相应的处理,是最常见的编辑指令;END{}:处理完最后一行文本之后执行
, 一般用来输出处理
AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯、彼得·温伯格和布莱恩·柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识,awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls
-l /bin/awk )
1、通过关键字 BEGIN 执行 BEGIN 块的内容,即 BEGIN 后花括号 {} 的内容。
2、完成 BEGIN 块的执行,开始执行body块。
3、读入有 \n 换行符分割的记录。
4、将记录按指定的域分隔符划分域,填充域,$0 则表示所有域(即一行内容),$1 表示第一个域,$n 表示第 n 个域。
5、依次执行各 BODY 块,pattern 部分匹配该行内容成功后,才会执行 awk-commands 的内容。
6、循环读取并执行各行直到文件结束,完成body块执行。
7、开始 END 块执行,END 块可以输出最终结果。
awk内置变量
ARGC | 命令行参数个数 |
ARGV | 命令行参数排列 |
ENVIRON | 支持队列中系统环境变量的使用 |
FILENAME | awk浏览的文件名 |
FNR | 浏览文件的记录数 |
FS | 设置输入域分隔符,等价于命令行 -F选项 |
NF | 浏览记录的域的个数 |
NR | 已读的记录数 |
OFS | 输出域分隔符 |
ORS | 输出记录分隔符 |
RS | 控制记录分隔符 |
awk -F(指定分隔符) : ‘{print $1}’ passwd | 打印passwd文件的以:为分隔符的第一列字符 |
awk -F : ‘{print $1$2}’ passwd | 打印第一列和第二列,不出现:分隔符 |
awk -F : ‘BEGIN{print “linux”}{print $2}’ passwd | 打印第二列,并且在最前面加上westos |
awk -F : ‘BEGIN{n=1}{print $1$2,n}’ passwd | 在第一列第二列后面 均写上1 |
awk -F : ‘BEGIN{n=1}{print $2,n++}’ passwd | 打印第二列,并且编号 |
awk -F : ‘BEGIN{n=1}{print n++,$1}’ | 打印第1列,并且编号 |
awk -F : ‘BEGIN{n=1}{print n++,$1}END{print “over”}’ passwd | 在后面写上over |
awk -F : ‘BEGIN{n=1}{print n++,$1}END{print NR}’ passwd | 在结尾输出行数 |
awk -F : ‘BEGIN{n=1}{print n++,$1}END{print NF}’ passwd | 在结尾输出列数 |
awk ‘/bash/{print}’ passwd | 输出包含bash的行的第一个字符 |
awk -F : ‘NR=3{print $1}’ passwd | 第三行的第一个 |
awk -F : ‘NR>=4&&NR<=6{print}’ passwd | 456行 |
awk -F : 'NR4 |
awk -F : ‘{print $1$2}’ passwd #打印第一列和第二列,不出现:分隔符
awk -F : ‘BEGIN{print “linux”}{print $2}’ passwd #打印第二列,并且在最前面加上westos
awk -F : ‘BEGIN{n=1}{print $1$2,n}’ passwd #在第一列第二列后面 均写上1
awk -F : ‘BEGIN{n=1}{print $2,n++}’ passwd #打印第二列,并且编号
awk -F : ‘BEGIN{n=1}{print n++,$1}’ #打印第1列,并且编号
awk -F : ‘BEGIN{n=1}{print n++,$1}END{print “over”}’ passwd #在打印完的文本后面写上over
awk -F : ‘BEGIN{n=1}{print n++,$1}END{print NR}’ passwd #在结尾输出行数
awk -F : ‘BEGIN{n=1}{print n++,$1}END{print NF}’ passwd #在结尾输出列数
awk ‘/bash/{print}’ passwd #输出包含bash的行的第一个字符
awk -F : ‘NR=3{print $1}’ passwd #第三行的第一个
awk -F : ‘NR>=4&&NR<=6{print}’ passwd #456行
awk -F : 'NR4||NR6{print}’ passwd #4和6行
awk编程
cat /etc/passwd |awk -F ':' '{print $1"\t"$7}'
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,
然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域, 1 表 示 第 一 个 域 , 1表示第一个域, 1表示第一个域,n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,linenumber:3,columns:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,linenumber:4,columns:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh
#使用printf替代print,可以让代码更加简洁,易读
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
变量和赋值
#除了awk的内置变量,awk还可以自定义变量。
#下面统计/etc/passwd的账户人数
awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is 40
#count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。
#这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:
awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd
[start]user count is 0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is 40
#统计某个文件夹下的文件占用的字节数
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
[end]size is 8657198
#如果以M为单位显示:
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
[end]size is 8.25889 M
#注意,统计不包括文件夹的子目录。
条件语句
awk中的条件语句是从C语言中借鉴来的,见如下声明方式:
if (expression) {
statement;
statement;
... ...
}
if (expression) {
statement;
} else {
statement2;
}
if (expression) {
statement1;
} else if (expression1) {
statement2;
} else {
statement3;
}
统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹):
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
[end]size is 8.22339 M
循环语句
awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同。
数组
因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。
#显示/etc/passwd的账户
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
0 root
1 daemon
2 bin
3 sys
4 sync
5 games
......
未完
在这里插入代码片