1、查找文件命令传统上分为三种:grep、egrep、fgrep正则表达式
三种命令的区别在于:fgrep是惟一支持并行匹配多个字符串的版本;而grep与egrep只能匹配单个正则表达式。数据库
grep默认行为模式: grep == grep -F fgrep == grep -F egrep == grep -Eapache
2、说到grep就不得不提起正则:less
这里特指符合POSIX标准的正则表达式,它符合如下两个特色:工具
1 特定于locale的字符序列顺序和等价字符命令行
2 没必要关心系统底层的字符集设计
正式讲正则以前插播一小段精品广告,他们是关于sed(stream editor)、awk、Perl、Tcl、more/less等,这些工具程序都有一个共同点,就是都沿用了某一种正则表达式形式来强化自己的功能。xml
首先讲到的是三类特殊符号:排序
1 排序[..ch..]ip
2 等价[=e=]
3 字符集[:xxx:]
另外一个是后向引用,他在寻找重复字以及匹配引号时特别好用: \(["']\).*\1 匹配以单引号或双引号括起来的字
区间表达式:将一个或两个数字,放在\{与\}之间,有三种变化:
\{n\}: 重现n次 \{n,\}: 重现至少n次 \{n,m\}: 重现n至m次(n与m的值必须介于0至RE_DUP_MAX,该值可经过命令getconf RE_DUP_MAX得到)
扩展正则表达式:
匹配单个字符,如左方括号、连字符、右方括号或是反斜杠,应该用[\ [\-\] \\]
交替,即垂直的一条线,或称为管道字符(|)。他是ERE运算符中优先级最低的。
分组,((...))。和其余字符结合起来使用时,分组仍是很是好用的。举个例子:
^abcd|efgh$意思是“匹配字符串的起始处是否有abcd,或者结尾处是否有efgh”,和^(abcd|efgh)$不同,后者表示的是“找一个正式abcd或正式efgh的字符串”。
这里要特别注意。
3、文本文件里的替换
这一小节是重点,由于里面涉及到一个很庞大的概念,即sed。sed最初的设计是用来以批处理的方式而不是交互的方式来编辑文件。然而,在Shell脚本里,sed主要用于一些简单的文本替换。
sed基本用法:
1 一般在管道(pipeline)中间使用sed,以执行替换操做。作法是使用s命令,举例以下:
sed 's/:.*//' /etc/passwd | sort -u //删除第一个冒号以后的内容及排序列表并删除重复部分
2 更新文件并备份源文件,举例以下:
假如目前hello.xml中有这样一段话,China,which is a most strong country of the world.
sed 's/China/&, the second biggest country of Asia/' < hello.xml.old > hello.xml
这样就在原来的文档中插入了一段话,同时将原有的hello.xml内容备份在文件hello.xml.old中
3 经过-e选项使用多个sed实体,例如:
sed -e 's/China/Russia/g' -e 's/strong/large/g' hello.xml > hello2.xml
不过,若是你有不少要编辑的项目,这种形式就很恐怖。因此,将编辑命令全放进一个脚本里,再使用sed搭配-f选项会更好:
$ cat hello.sed
s/China/Russia/g
s/strong/large/g
...
$ sed -f hello.sed hello.xml > hello2.xml
sed的运做原理:
命令行上的每一个文件名会依次打开与读取。若是没有文件,则使用标准输入,用“-”表示。
sed逐行读取每一个没减,再将读取到的行放到内存中的某个区域——称为模式空间。区域中的内容会随着编辑命令应用在其上的操做不断更新其中的内容。当全部操做完成后,sed会将模式空间的最后内容打印到标准输出,再回到开始的位置,读取下一行。
4、字段处理
其实数据也能够视为记录与字段的结合,一条记录是相关信息的单个集合,可视做数据库中的data,而字段指的就是记录的组成部分。能够看作是数据库中的field。
cut、join与awk
cut与join的用法这里再也不作过多讲述,只要记住一个是剪切字段,一个是拼接字段就好了,使用的时候借助-man便可,很简单。
这里主要介绍下能够和sed势均力敌的一个重要指令——awk
awk用法:
awk主要用于取出字段并从新编排和一些简易的文本处理。但因为他自己锁提供的功能完备,已经能够算是一个很好用的程序语言了。
awk设计的重点在字段与记录上:awk读取输入记录,而后自动将各个记录切分为字段。或者,awk特别之处就是:也能够设置它为一个完整的ERE,这种状况下,每个匹配在该ERE的文本都将视为字段分隔字符。
awk的输入、输出分隔字符用法是分开的,这点与其余工具程序不一样。例如:
$ awk -F: '{ print $1, $5 }' /etc/passwd
-F选项会自动地设置FS变量。程序没必要直接参照FS变量,也不用必须管理读取的记录并将它们分割为字段:awk会自动完成这些事。
$ awk -F: -v 'OFS=**' '{ print $1, $5 }' /etc/passwd
root**root
...
haldaemon**HAL daemon
avahi**Avahi daemon
avahi-autoipd**avahi-autoipd
apache**Apache
ntp**
...
$ awk -F: '{ print "User", $1, "is really", $5 }' /etc/passwd
User root is really root
...
User daemon is really daemon
User adm is really adm
User lp is really lp
User sync is really sync
...
好了,第一节先到这里。