01grep, egrep, fgrep
* grep:
传统的 grep 程序, 在没有参数的情况下, 只输出符合 RE 字符串之句子. 常见参数如下:
-v: 逆反模示, 只输出"不含" RE 字符串之句子.
-r: 递归模式, 可同时处理所有层级子目录里的文件.
-q: 静默模式, 不输出任何结果(stderr 除外. 常用以获取 return value, 符合为 true, 否则为 false .)
-i: 忽略大小写.
-w: 整词比对, 类似 \<word\> .
-n: 同时输出行号.
-c: 只输出符合比对的行数.
-l: 只输出符合比对的文件名称.
-o: 只输出符合 RE 的字符串. (gnu 新版独有, 不见得所有版本都支持.)
-E: 切换为 egrep .
* egrep:
为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说:
- grep 之下不支持 ? 与 + 这两种 modifier, 但 egrep 则可.
- grep 不支持 a|b 或 (abc|xyz) 这类"或一"比对, 但 egrep 则可.
- grep 在处理 {n,m} 时, 需用 \{ 与 \} 处理, 但 egrep 则不需.
诸如此类的... 我个人会建议能用 egrep 就不用 grep 啦... ^_^
* fgrep:
不作 RE 处理, 表达式仅作一般字符串处理, 所有 meta 均失去功能.
02 grep 输入字符串参数、变量时,使用双引号括起来
例如:grep "zpp"
grep "$myvalue"
常用选项:
-c 只输出匹配行的计数。
-i 不区分大小写(只适用于单字符)。
-h 查询多文件时不显示文件名。
-l 查询多文件时只输出包含匹配字符的文件名。
-n 显示匹配行及行号。
-s 不显示不存在或无匹配文本的错误信息。
-v 显示不包含匹配文本的所有行。
03 例子
1】在所有文件中搜索单词 “sort it”
grep "sort it" *
2】输出匹配行的总数
grep -c "sort it" *
3】输出行号
grep -n "sort it" *
注:第一行为总行数,
4】显示非匹配行
grep -v "sort it" *
5】精确匹配:使用\>
抽取字符串“ sort it”,返回结果包含诸如sort it zpp等包含“sort it”的其他字符串,实际上应精确抽取只包含sort it的各行。
grep "sort it\>" *
6】不区分大小写
grep -i "sort it" *
7】行首不是4或8
grep ^[^48] tmp.txt
8】如果是字符串48
grep -v ^[^48] tmp.txt
9】匹配以K开头D结尾,总长度为5的所有代码
grep K...D TMP.txt
10】日期查询
查询所有以5开始以1 9 9 6或1 9 9 8结尾的所有记录
grep '5.*199[68]' tmp.txt
11】
g r e p命令加- E参数(等价于egrep),这一扩展允许使用扩展模式匹配。例如,要抽取城市代码为2 1 9或2 1 6
grep -E 219|216
12】空行总行数
grep -c '^s' tmp.txt
13】诸如$ . ' " * [] ^ | \ + ? ,必须在特定字符前加\
查询包含“.”的所有行
grep '\.' tmp.txt
14】查询文件名c o n f t r o l l . c o n f(这是一个配置文件)
grep 'conftroll\.conf' tmp.txt
15】查询IP
xxx.xxx.xxx
grep [0-9]\{3\}\.grep [0-9]\{3\}\.grep [0-9]\{3\}
16】类名
类名及其等价的正则表达式类等价的正则表达式类等价的正则表达式
[ [ : u p p e r : ] ] 等价于 [ A - Z ]
[ [ : a l n u m : ] ] 等价于 [ 0 - 9 a - zA-Z]
[ [ : l o w e r : ] ] 等价于 [ a - z ]
[ [ : s p a c e : ] ] 等价于 空格或t a b键
[ [ : d i g i t : ] ] 等价于 [ 0 - 9 ]
[ [ : a l p h a : ] ] 等价于 [ a - z A - Z ]
例子
取以5开头,后跟至少两个大写字母
grep '5[ [ : u p p e r : ] ][ [ : u p p e r : ] ]' tmp.txt
17】通配符 *
行尾查询一个单词wo
grep "wo$" tmp.txt
18】如要保存g r e p命令的查询结果,可将命令输出重定向到一个文件。
grep "wo$" tmp.txt > /ect/tmp/zpp.out
19】对一个字符串使用grep
str="sdkkdk"
echo $str | grep "ddd"
-------------------------------------------------------------------------------------------------------------------------------
04 egrp
支持所有的正则表达式
r e p的一个显著特性是可以以一个文件作为保存的字符串,然后将之传给e g r e p作为参数,为此使用- f开关。如果创建一个名为g r e p s t r i n g s的文件,并输入4 8 4和4 7:
场合:当匹配大量模式时, - f开关很有用
01】
[root@Linux_chenwy sam]# vi grepstrings
[root@Linux_chenwy sam]# cat grepstrings
484
47
egrep -f grepstrings data.f
47 Oct 3ZL1998 LPSX 43.00 KVM9D 512
484 nov 7PL1996 CAD 49.00 PLV2C 234
02】
查询存储代码3 2 L或2 C C,可以使用(|)符号,意即“|”符号两边之一或全部。
egrep '(32L2CC)' tmp.txt
03】
要查看在系统中是否有帐号l o u i s e、m a t t y或pauline ,使用w h o命令并管道输出至e g r e p。
who | egrep ‘(louise|matty|pauline)’
04】可以使用^符号排除字符串。如果要查看系统上的用户,但不包括m a t t y和p a u l i n e
who | egrep -v '^(matty|pauline)'
05】如果要查询一个文件列表,包括s h u t d o w n、s h u t d o w n s、r e b o o t和r e b o o t s,使用e g r e p可容易地实现。
egrep '(shutdown|reboot)(s)?' *
----------------------------------------------------------------------------------------------
05 AWK
awk 适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行需要特殊技巧程序设计。与某些语言不同,awk 的语法较为常见。它借鉴了某些语言的一些精华部分,如 C 语言、python 和 bash(虽然在技术上,awk 比 python 和 bash 早创建)。awk 是那种一旦学会了就会成为您战略编码库的主要部分的语言。
原理:
输入命令:awk '{ print }' /etc/passwd
您将会见到 /etc/passwd 文件的内容出现在眼前。现在,解释 awk 做了些什么。调用 awk 时,我们指定 /etc/passwd 作为输入文件。执行 awk 时,它依次对 /etc/passwd 中的每一行执行 print 命令。所有输出都发送到 stdout,所得到的结果与与执行catting /etc/passwd完全相同。
现在,解释 { print } 代码块。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 C 语言。在代码块中只有一条 print 命令。在 awk 中,如果只出现 print 命令,那么将打印当前行的全部内容。
这里是另一个 awk 示例,它的作用与上例完全相同:
$ awk '{ print $0 }' /etc/passwd
在 awk 中,$0 变量表示整个当前行,所以 print 和 print $0 的作用完全一样。
如果您愿意,可以创建一个 awk 程序,让它输出与输入数据完全无关的数据。以下是一个示例:
$ awk '{ print "" }' /etc/passwd
只要将 "" 字符串传递给 print 命令,它就会打印空白行。如果测试该脚本,将会发现对于 /etc/passwd 文件中的每一行,awk 都输出一个空白行。再次说明, awk 对输入文件中的每一行都执行这个脚本。以下是另一个示例:
$ awk '{ print "hiya" }' /etc/passwd
运行这个脚本将在您的屏幕上写满 hiya。
1】域和记录
a w k执行时,其浏览域标记为$ 1,$ 2 . . . $ n。这种方法称为域标识。如果希望打印一个有5个域的记录的所有域,不必指明$ 1 , $ 2 , $ 3 , $ 4 , $ 5,可使用$ 0,意即所有域。
原理过程:Aw k浏览时,到达一新行,即假定到达包含域的记录末尾,然后执行新记录下一行的读动作,并重新设置域分隔。
2】抽取域的例子
1. 抽取域
真正执行前看几个例子,现有一文本文件g r a d e . t x t,记录了一个称为柔道数据库的行信息。
01.$ cat grade.txt
02.M.Tans 5/99 48311 Green 8 40 44
03.J.Lulu 06/99 48317 green 9 24 26
04.P.Bunny 02/99 48 Yellow 12 35 28
05.J.Troll 07/99 4842 Brown-3 12 26 26
06.L.Tansl 05/99 4712 Brown-2 12 30 28
复制代码
此文本文件有7个域,即(1)名字、(2)升段日期、(3)学生序号、(4)腰带级别、(5)年龄、(6)目前比赛积分、(7)比赛最高分。
因为域间使用空格作为域分隔符,故不必用- F选项划分域,现浏览文件并导出一些数据。在例子中为了利于显示,将空格加宽使各域看得更清晰。
2. 保存a w k输出
有两种方式保存s h e l l提示符下a w k脚本的输出。最简单的方式是使用输出重定向符号>文件名,下面的例子重定向输出到文件w o w。
01.$ awk '{print $0}' grade.txt >wow
02.$ cat grade.txt
复制代码
使用这种方法要注意,显示屏上不会显示输出结果。因为它直接输出到文件。只有在保证输出结果正确时才会使用这种方法。它也会重写硬盘上同名数据。
第二种方法是使用t e e命令,在输出到文件的同时输出到屏幕。
awk '{print $0}' grade | tee wow
3.打印所有记录
awk '{print $0}' grade.txt
4.单独打印记录
假定只打印学生名字和腰带级别,通过查看域所在列,可知为f i e l d - 1和f i e l d - 4,因此可以使用$ 1和$ 4,但不要忘了加逗号以分隔域。
awk '{print $1,$4}' grade.txt
5. 打印报告头
打印信息头放置在B E G I N模式部分,因为打印信息头被界定为一个动作,必须用大括号括起来。在a w k查看第一条记录前,信息头被打印。
01.$ awk 'BEGIN {print "Name Belt\n-----------------------------------"}{print $1"\t",$4}' grade.txt
02.Name Belt
03.-----------------------------------
04.M.Tans Green
05.J.Lulu green
06.P.Bunny Yellow
07.J.Troll Brown-3
08.L.Tansl Brown-2
6.打印信息尾
E N D语句在所有文本处理动作执行完之后才被执行。
01.$ awk 'BEGIN {print "Name\n--------"}{print $1} END {print "end-of-report"}' grade.txt
02.Name
03.--------
04.M.Tans
05.J.Lulu
06.P.Bunny
07.J.Troll
08.L.Tansl
7.awk 键盘输入
如果在命令行并没有输入文件g r a d e . t x t,将会怎样?
01.$ awk 'BEGIN {print "Name\n--------"}{print $1} END {"end-of-report"}'
02.Name
03.--------
B E G I N部分打印了文件头,但a w k最终停止操作并等待,并没有返回s h e l l提示符。这是因为a w k期望获得键盘输入。因为没有给出输入文件, a w k假定下面将会给出。如果愿意,顺序输入相关文本,并在输入完成后敲<Ct r l - D >键。如果敲入了正确的域分隔符, a w k会像第一个例子一样正常处理文本。这种处理并不常用,因为它大多应用于大量的打印稿。
8.shell基础九:awk
脚本解释语言,unix下比较强大的有sed,awk,perl,python等;sed,awk,perl比较传统的,新兴的python有些平台已经支持,但lua各个平台都还没有不过可以很容易的移植源代码
实际上,perl要比sed,awk出现要晚的多,perl诞生的初衷,就是要取代awk,sed,grep等"传统"的数据处理工具
-------------------------------------------------------------------------------
s e d
一个非交互性文本流编辑器。
" 抽取域。
" 匹配正则表达式。
" 比较域。
" 增加、附加、替换。
" 基本的s e d命令和一行脚本。
因为s e d是一个非交互性编辑器,必须通过行号或正则表达式指定要改变的文本行。
和g r e p与a w k一样, s e d是一种重要的文本过滤工具,或者使用一行命令或者使用管道与g r e p与a w k相结合。
下面是使用s e d定位文本的一些方式。
01.x x为一行号,如1
02.x , y 表示行号范围从x到y,如2,5表示从第2行到第5行
03./ p a t t e r n / 查询包含模式的行。例如/ d i s k /或/[a-z]/
04./ p a t t e r n / p a t t e r n / 查询包含两个模式的行。例如/ d i s k / d i s k s /
05.p a t t e r n / , x 在给定行号上查询包含模式的行。如/ r i b b o n / , 3
06.x , / p a t t e r n / 通过行号和模式查询匹配行。3 . / v d u /
07.x , y ! 查询不包含指定行号x和y的行。1 , 2 !
例子:
1]s e d例子中使用下述文本文件q u o t e . t x t。
01.[sam@Linux_chenwy sam]$ cat quote.txt
02.The honeysuckle band played all night long for only $90.
03.It was an evening of splendid music and company.
04.Too bad the disco floor fell through at 23:00.
05.The local nurse Miss P.Neave was in attendance.
2]使用p(rint)显示行
只打印第二行,用-n
sed -n '2p' quote.txt
3]打印范围
可以指定行的范围,现打印1到3行,用逗号分隔行号。
sed -n '1,3p' quote.txt
4] 使用模式/ p a t t e r n /格式
匹配字符串"The"
sed -n '/The/p' quote.txt
5] 使用模式和行号进行查询
从第4行开始匹配"The"
sed -n '4,/The/p' quote.txt
6] 匹配元字符
匹配元字符$前,必须使用反斜线\屏蔽其特殊含义。模式为/\$/ p。
sed -n '/\$/p' quote.txt
7] 显示整个文件
要打印整个文件,只需将行范围设为第一行到最后一行1 , $。$意为最后一行。
sed -n '1,$p' quote.txt
8] 任意字符
匹配任意字母,后跟任意字母的0次或多次重复,并以i n g结尾,模式为/ . * i n g /。
sed -n '/.*ing/p' quote.txt
9]首行
要打印文件第一行,使用行号:
sed -n '1p' quote.txt
10] 尾行
sed -n '$p' quote.txt
11]打印行号
要打印行号,使用等号=。打印模式匹配的行号,使用格式/ p a t t e r n / =。
01.[sam@Linux_chenwy sam]$ sed -e '/music/=' quote.txt
02.The honeysuckle band played all night long for only $90.
03.2
04.It was an evening of splendid music and company.
05.Too bad the disco floor fell through at 23:00.
06.The local nurse Miss P.Neave was in attendance.
整个文件都打印出来,并且匹配行打印了行号。如果只关心实际行号,使用- e选项。
01.[sam@Linux_chenwy sam]$ sed -n '/music/=' quote.txt
02.2
如果只打印行号及匹配行,必须使用两个s e d命令,并使用e选项。第一个命令打印模式匹配行,第二个使用=选项打印行号,格式为sed -n -e /pattern/p -e /pattern/=
01.[sam@Linux_chenwy sam]$ sed -n -e '/music/p' -e '/music/=' quote.txt
02.It was an evening of splendid music and company.
03.2
12] 新版本的sed(GNU sed version 4.0.5)带有-i选项,允许直接编辑修改文件内容而不需要重定向到临时文件
13] 附加文本
要附加文本,使用符号a \,可以将指定文本一行或多行附加到指定行。如果不指定文本放置位置, s e d缺省放在每一行后面。附加文本时不能指定范围,只允许一个地址模式。文本附加操作时,结果输出在标准输出上。注意它不能被编辑,因为s e d执行时,首先将文件的一行文本拷贝至缓冲区,在这里s e d编辑命令执行所有操作(不是在初始文件上),因为文本直接输出到标准输出,s e d并无拷贝。
要想在附加操作后编辑文本,必须保存文件,然后运行另一个s e d命令编辑它。这时文件的内容又被移至缓冲区。
附加操作格式如下:
01.[address]a\
02.text\
03.text\
04.......
05.text
复制代码
地址指定一个模式或行号,定位新文本附加位置。a\ 通知s e d对a \后的文本进行实际附加操作。观察格式,注意每一行后面有一斜划线,这个斜划线代表换行。s e d执行到这儿,将创建一新行,然后插入下一文本行。最后一行不加斜划线, s e d假定这是附加命令结尾。
例子:
创建脚本文件a p p e n d . s e d:
第一行是s e d命令解释行。脚本在这一行查找s e d以运行命令,这里定位在/ b i n。
第二行以/ c o m p a n y /开始,这是附加操作起始位置。a \通知s e d这是一个附加操作,首先应插入一个新行。
第三行是附加操作要加入到拷贝的实际文本。
输出显示附加结果。如果要保存输出,重定向到一个文件。
01.[sam@chenwy sam]$ cat append.sed
02.#!/bin/sed -f
03./company/ a\
04.Then suddenly it happed.
保存它,增加可执行权限,运行
01.[sam@chenwy sam]chmod u+x append.sed
02.[sam@chenwy sam]$ ./append.sed quote.txt
03.The honeysuckle band played all night long for only $90.
04.It was an evening of splendid music and company.
05.Then suddenly it happed.
06.Too bad the disco floor fell through at 23:00.
07.The local nurse Miss P.Neave was in attendance.
或直接用命令行:
01.[sam@chenwy sam]$ sed "/company/a\Then suddenly it happened." quote.txt
02.The honeysuckle band played all night long for only $90.
03.It was an evening of splendid music and company.
04.Then suddenly it happened.
05.Too bad the disco floor fell through at 23:00.
06.The local nurse Miss P.Neave was in attendance.
14】 插入文本 匹配的行前插入
[sam@chenwy sam]$ sed "/company/i\utter confusion followed." quote.txt
The honeysuckle band played all night long for only $90.
utter confusion followed.
It was an evening of splendid music and company.
Too bad the disco floor fell through at 23:00.
The local nurse Miss P.Neave was in attendance.
也可以指定行:
01.[sam@chenwy sam]$ cat insert.sed
02.#!/bin/sed -f
03.4 i\
04.Utter confusion followed.
复制代码
执行结果
01.[sam@chenwy sam]$ chmod u+x insert.sed
02.[sam@chenwy sam]$ ./insert.sed quote.txt
03.The honeysuckle band played all night long for only $90.
04.It was an evening of splendid music and company.
05.Too bad the disco floor fell through at 23:00.
06.Utter confusion followed.
07.The local nurse Miss P.Neave was in attendance.
15】 修改文本
01.[sam@chenwy sam]$ cat change.sed
02.#!/bin/sed -f
03.3 c\
04.The office Dibble band played well.
01.[sam@chenwy sam]$ chmod u+x change.sed
02.[sam@chenwy sam]$ ./change.sed quote.txt
或命令行:
01.[sam@chenwy sam]$ sed "/honeysuck/c\The Office Dibble band played well." quote.txt
15】可以对同一个脚本中的相同文件进行修改、附加、插入三种动作匹配和混合操作。
01.[sam@chenwy sam]$ cat mix.sed
02.#!/bin/sed -f
03.1 c\
04.The Dibble band were grooving.
05.
06./evening/ i\
07.They played some great tunes.
08.
09.3 a\
10.Where was the nurse to help?
执行:
$ chmod u+x mix.sed
02.[sam@chenwy sam]$ ./mix.sed quote.txt
16】删除文本
删除第一到第三行:
01.[sam@chenwy sam]$ sed '1,3d' quote.txt
删除最后一行:
也可以使用正则表达式进行删除操作。下面的例子删除包含文本‘ N e a v e’的行。
01.[sam@chenwy sam]$ sed '/Neave/d' quote.txt
17】替换文本
替换命令用替换模式替换指定模式,格式为:
01.[ a d d r e s s [,address]] s/ pattern-to-find /replacement-pattern/[g p w n]
复制代码
s选项通知s e d这是一个替换操作,并查询p a t t e r n - t o - f i n d,成功后用r e p l a c e m e n t - p a t t e r n替换它。
替换选项如下:
g 缺省情况下只替换第一次出现模式,使用g选项替换全局所有出现模式。
p 缺省s e d将所有被替换行写入标准输出,加p选项将使- n选项无效。- n选项不打印输出结果。
w 文件名使用此选项将输出定向到一个文件。
例子
如替换n i g h t为N I G H T,首先查询模式n i g h t,然后用文本N I G H T替换它。
01.[sam@chenwy sam]$ sed 's/night/NIGHT/' quote.txt
要从$ 9 0 中删除$ 符号(记住这是一个特殊符号,必须用\ 屏蔽其特殊含义),在r e p l a c e m e n t - p a t t e r n部分不写任何东西,保留空白,但仍需要用斜线括起来。在s e d中也可以这样删除一个字符串。
01.[sam@chenwy sam]$ sed 's/\$//' quote.txt
02.The honeysuckle band played all night long for only 90.
03.It was an evening of splendid music and company.
04.Too bad the disco floor fell through at 23:00.
05.The local nurse Miss P.Neave was in attendance.