全部博文(26)
分类: LINUX
2014-02-04 23:25:20
摘自:[美]Harley Hahn:Unix & Linux大学教程
十四、过滤器:选取、排序、组合及变换
(1)选取包含特定模式的行:grep
除了搜索特定的字符串外,还可以对grep使用正则表达式。语法为:
grep [-cilLnrsvwx] pattern [file..]
其中pattern是要搜索的模式,file是文件名。
当指定包含标点符号或特殊字符的模式时,应将它们引用。例:
grep ‘:’ info
-c (count,统计)选项,该选项将显示所抽取行的数量
-i,忽略大小写
-n,在输出行的每一行前面写一个相对行号
-l(list name,列举文件名),grep不显示包含该模式的每行,而是将包含这种模式的文件名称写出来。
-L,显示不包含匹配模式的文件
-w,只搜索完整的单词
-v(reverse,相反)选择不包含特定模式的所有行
-x,查找那些完全由搜索模式构成的行
-r(recursive,递归)选项,搜索整个目录树
如果不希望看到无法读取某些文件的信息,可使用-s(suppress,抑制)选项
搜索整个文件系统中的某个模式,如:
grep -rs / ‘shutdown now’
(2)egrep
原始的grep只允许“基本的正则表达式”。而后来开发的egrep支持功能更强大的“扩展正则表达式”。
Unix系统通过命令egrep或者grep –E允许使用扩展正则表达式。
(3)选取以特定模式开头的行:look
语法为 look [-df] pattern file...
其中pattern是搜索的模式,file是文件名。
look不能从标准输入中读取数据,它必须从一个或多个文件中获取输入。严格地讲,look并不是过滤器,它只能用在管道开头。
-d(dictionary,字典)选项告诉sort只考虑字母和数字。当希望look忽略标点符号和其他特殊字符时,可以使用-d选项。-f(fold,同等)选项告诉sort忽略大写字母和小写字母之间的区别。
如果使用这两种sort选项准备数据,那么必须对look使用相同选项。例:
sort –df fresh soph junior senior > evaluations
look df A evaluations
选择look和grep的时机,基于简单和易用性选择。
look还可以查找以特定模式开头的所有单词,语法为look pattern。例:
look simult 输出 simultaneity simultaneous simultaneously simultaneousness
(4)排序数据:sort
sort程序可以执行两个相关的任务:排序数据以及查看数据是否已经有序。排序数据的sort程序语法为:
sort [-dfnru] [-o outfile] [infile...]
其中outfile是存放输出的文件的名称,infile是包含输入的文件的名称。
sort提供了一个特殊的选项(-o选项),允许将输出保存到任何希望的文件中。例:sort -o names names 在这个例子中,names中的原始数据将被保持,起到sort程序完成,然后输出才被写到文件中。
默认情况下,在排序数据时,sort程序查看整行。但是,如果希望,也可以告诉sort只检查一个或多个字段,但十分复杂,查问 info sort
-d选项,只查看字母、数字和空白符
-f选项,忽略大小写区别
-n选项,识别行开头或字段开头的数字,并按数字进行排序,这样的数字可以包含前导0、负号和小数点
-r选项,按反向顺序对数据排序
-u选项,相同行只留一行
检查数据是否有序
sort –c[u] [file]
-c选项告诉sort不希望排序数据,只希望知道数据是否已经有序
-u选项检查数据是否有重复行
(5)ASCII码:排序序列
ASCII码(American Standard Code for Information Interchange)
查看ASCII码,Linux man ascii FreeBSD less /usr/share/misc/ascii Solaris less /usr/pub/ascii
ASCII码排序原则:空格、数字、大写字母、小写字母。(SNUL)
(6)区域设置和排序序列
区域设置(locale)是一种技术规范,描述与特定文化的用户通信时应该使用的语言和习俗。
在Unix中,区域设置由一组标识语言、日期格式、时间格式、货币符号和其他文化习俗的环境变量所定义。特别的,有一个环境变量LC_COLLATE指定使用哪一种排序序列。
显示所有区域设置变量的值,包括LC_COLLATE,可用locale命令。
如果想知道自己系统支持哪些区域设置,可加-a选项。
在美国,Unix系统默认设置为两个区域设置中的一个。两个区域设置基本上是相同的,但是有不同的排序序列,这意味着当运行sort之类的程序时,结果会根据使用的区域设置不同而有所变化。
第一种美国区域设置基于ASCII码。这种区域设置有两个名称。它被称为C区域设置或POSIX区域设置。第二种区域设置基于美国英语,命名为en_US。
C区域设置使用ASCII排序序列,大写字母在小写字母之前。
en_US区域设置使用字典排序序列,小写字母和大写字母成对分组,aAbBcCdD...zZ,这种模式比较自然,因为它以字典顺序组织单词和字符。
建议将区域设置默认为C区域设置。因为它使用传统的ASCII排序序列。从长远看,这比使用en_US区域设置和字典排序序列产生的问题更少。
如果系统使用en_US区域设置,那么需要将LC_COLLATE环境变量改为C或POSIX。(永久地改变环境变量,可将其放入登录文件中)
Bourne Shell export LC_COLLATE=C 或者 export LC_COLLATE=POSIX
C-shell setenv LC_COLLATE C 或者 setenv LC_COLLATE POSIX
(7)查找重复行:uniq
uniq程序可执行4项任务,消除、选取、统计重复行和选取唯一行
uniq [-cdu] [infile [outfile]]
其中infile是输入文件的名称,outfile是输出文件的名称。
uniq的输入必须是有序的。
只查看重复行,使用-d选项;
只查看非重复行,使用-u选项;
统计重复行出现的次数,使用-c选项。
(8)合并两个文件中的有序数据:join
join基于特定字段的值将两个有序文件组合在一起。语法
join [-i] [-a1 | -V1] [-a2| -v2] [-1 field1] [-2 field2] file1 file2
其中field1和field2是引用特定字段的数字,file1和file2是包含有序数据的文件的名称。
当join读取输入时,忽略前导空白符,也就是行首的空格和制表符。
当基于匹配的字段组合两组数据时,称为联接。用来匹配的具体字段为联接字段。默认是每个文件的第一个字段,可另指定。
为了创建一个联接,程序需要在两个文件中查找行对,也就是说字段是拥有相同值的行。对于每个行对来说,join生成包含了部分的输出:公共联接字段值、每一个文件中行的其余字段,第二个文件中行的其余部分。
-a1选项告诉join输出第1个文件中的所有行;-a2选项输出第2个文件中的所有行。这种输出称为外联接。
只查看不匹配的行,则可使用-v1或者-v2选项。
-i选项忽略大小写字母的区别。
join假定联接字段是每个文件中的第一个字段。通过-1和-2选项可以指定使用不同的联接字段。例:
join -1 3 -2 4 data statistics
(9)由偏序创建合序:tsort
从数学术语上讲,每个约束都称为一个偏序;困为它们只指定了一些(不是全部)字段的顺序。
tsort的任务就是分析一组偏序,其中每一个偏序代表一个约束,并计算满足全部约束的合序。语法为
tsort [file] file是文件的名称
输入的每一行必须包含一对由空白符(空格或制表符)分隔的字符串,每对字符串都代表一个偏序。
(10)在二进制文件中搜索字符串:strings
strings [-length] [file...]
其中length是要显示的字符串的最小长度,file是文件的名称,通常是一个路径名。
(11)转换字符:tr
tr(translate,转换)程序可以对字符执行3种不同的运算:将字符变为其他字符、将连续出现的字符换成一个单独的字符、删除指定的字符。语法为:
tr [-cds] [set1] [set2]
其中set1和set2是字符组
如 tr a A < old, 将所有的a替换为A
tr还可以字符范围,例: tr A-Z a-z < old > new
范围可以是任意希望的字符组,只要它们在所使用的排序序列中形成连续序列。
tr程序可识别的特殊代码
+++++++++++++++++++++++++++++++++++++++
代码 控制键 八进制码 名称
\b ^H \010 退格
\t ^I \011 制表符
\n ^J \012 新行/换行符
\r ^M \015 回车
\\ 无 无 反斜线
++++++++++++++++++++++++++++++++++++++++
-s选项告诉tr第一组中的多个连续字符应该替换为一个单独的字符。例:
tr –s 0-9 X
-d选项,删除指定的字符,需要定义一组字符。例:
tr –d ‘()’
-c选项,匹配所有不在第一组中的字符,例:
tr –c ‘ \n’ X
(12)sed
sed执行的最有用的操作就是进行简单的替换。语法为:
sed [-i] command | -e command... [file...]
其中command是一个sed命令,file是输入文件的名称。
-i选项,这将导致sed程序将输出保存到一个临时文件,一旦所有的数据都成功处理,sed就将临时文件复制到原始文件。
sed替换的命令是s,s命令的语法有两种形式:
[/address | pattern/] s /search/replacement/[g]
其中address是输入流中一个或多个行的地址,pattern是一个字符串,search是正则表达式,replacement是替换文本,例如 s/harley/Harley/ 该命令告诉sed搜索输入流中的每一行,查找字符串”harley”,如果找到这个字符串,则将其改变为”Harley”。默认情况下,sed只改变每一行第一个出现的匹配字符串。
如果要改变所有匹配的字符串,则需要在命令的末尾键入后缀g,代表global;
s/harley/Harley/g
默认情况下,sed对数据流中的每一行都执行它的操作,为了改变这一点,可以在命令前面加上一个地址,语法为
number[,number] | /regex/
其中number是行号,regex是正则表达式,例:
sed ‘5,10s/harley/Harley/g’ names
为了方便起见,可以用字符串$指定数据的最后一行。
另一种指定行号的方法是使用正则表达式或者被/(斜线)字符包围的字符串。例 sed ‘/ok/s/harley/Harley/g’ names
sed实际上是一种文本操作编程语言的解释器。因此可以编写包含任意多个sed命令的程序,并将程序存储在文件中,每当需要时就可以运行。
为了这样做,需要使用-f命令标识程序文件。例如,为了运行存储在文件instructions中的sed程序,并使用文件input中的数据,可以使用命令:
sed -f instructions input
可以指定任意多的sed命令,只要在sed命令之前使用一个-e选项。例:
sed -i -e ‘s/mon/Monday/g’ \
-e ‘s/tue/Tuesday/g’ \
-e ‘s/wed/Wednesday/g’ \
-e ‘s/thu/Thursday/g’ \
-e ‘s/fri/Friday/g’ \
-e ‘s/sat/Saturday/g’ \
-e ‘s/sun/Sunday/g’ calendar