该进入第四章了,刚才看到一个帖子标题:我空有一身泡妞的好本领,但可惜自己是个妞。汗~这个。。。音乐无国界嘛,这个不应该也没性别界么?
第四章文本处理工具
书中先说明了以下排序的规则,数值的就不用说了,该大就大该小就小,但是字符型很多时候是区分声调或者重音的。在命令行中输入locale查看自己系统的编码配置。默认的是系统配置里的,但是可以自己设置排序的编码。如:
下边介绍以下排序命令sort:
语法: sort [ options ] [ file(s} ]
主要选项: -b 忽略开头的空白
-c 检查输入是否已正确地排序。如果未排序,则退出码为非零值,不会有任何输出
-d 字典顺序,仅文字数字和空白才有意义。
-g 一般数值:以浮点数字类型比较字段。仅GNU版本提供此选项功能
-f 将混用的字母都看作相同大小写,即忽略大小写。
-i 忽略无法打印的字符。
-k 定义排序键值字段
-m 将已排序的输入文件,合并为一个排序后的输出数据流
-n 以整数类型比较字段
-o outfile 将输出写到指定文件
-r 倒置排序由大到小,默认由小到大
-t char 使用单个字符char作为默认的字段分隔符取代空白字符
-u 只有唯一记录,丢弃所有具有相同键值的记录只留第一条。
另外排序键值字段类型标识,即-k一个字段之后的修饰符字母:
b 忽略开头的空白
d 字典顺序
f 不区分大小写
g 以一般的浮点数进行比较,只适用GNU版本
i 忽略无法打印的字符
n 以整数数字比较
r 倒置排序顺序
字段以及字段里的字符是由1开始编号的。如果仅指定一个字段编号,则排序键值会自该字段的起始处开始,一直继续到记录的结尾(而非字段结尾)。
如果给的是一对用逗号隔开的字段数字,则排序键值将由第一个字段值起开始,到第二个指定字段结尾结束。可能出现多个-k,会从第一个开始。
例子:
有时候我们还十分关心排序的稳定性,默认情况下是不稳定的,但是GNU实现了coreutils包弥补了不足,可以通过--stable选项来解决稳定性问题。(不懂稳定性的简单说一下:意思就是排序键值等同的时候需要以输入顺序来输出,即排序不打乱输入顺序)
有时候我们还需要解决输入数据的重复问题,sort -u能够解决一些,但是它消除的操作依据的是匹配的键值,而非匹配的记录。uniq命令提供另一种过滤数据的方式:它常用于管道中,用来删除已适用sort排序完成的重复记录。uniq有3个好用的选项:-c 可在每个输出行之前加上该行的重复次数。 -d选项则用于仅显示重复的行。 -u仅显示未重复的行。这里需要注意一点,uniq处理数据前是需要sort对数据进行排序的!
另外我们处理大量这样的数据的时候,我们需要重新格式化段落以方便我们使用或阅读。这时候可以使用fmt命令,有两个常用的选项:-s 仅切割较长的行,短行不会合并 ; -w n 则设置输出行宽度为n个字符(默认75个左右)。要考虑fmt移植性的请另行查询文档。
这里对可能使用到的统计行数、字数、字符数的wc命令做一个介绍,选项有-c 字节数 -l行数 -w 字数 。默认情况下给出行数 字数 字节数。
好了,处理了那么多文本,我们可能要打印出来看看,unix里支持的打印功能包括两类不同的命令,但拥有相同的功能,商用的unix系统与GNU/linux通常两种都支持,不过BSD系统仅支持Berkeley风格,POSIX则只定义了lp命令。
两套命令的例子:
然后是System V风格的:
有时需打印数据需要加上页码或者时间戳,可以使用pr预处理要打印的数据。
语法:pr [ options ] [ file(s) ]
主要选项:
-cn 产生n栏的输出,可以简化成-n
-f 在首页之后的每一页标题前置一个ASCII分页字符标题,(有的环境下是-F)
-h althdr 将页标题内的文件名称,改用字符串althdr取代。
-ln 产生n行的页面
-on 输出位移n个空白
-t 不显示标题
-wn 每行至多n个字符。以单栏输出而言,如有需要会将较长的行切分绕回至另外一行;否则,在多栏输出的情况下,会截去长的行以符合指定。样例:
pr -f -l60 -o10 -w65 file(s) | lp 。
还有其他打印工具,这里说的比较简单,有这方面需求可以再搜些文档看看。
第五章管道的神奇魔力
在linux下的管理性文件,大部分都是文本文件,可以直接编辑阅读的,这些文件大部分放在标准目录:/etc下。我们写shell脚本的时候大部分时候都是在处理文本信息,而管道是可以一直顺序着连着使用的 如 .... | ... | ... 这样,书中举了个连着使用5个管道的处理passwd文件的例子说很厉害,大致就是这样。然后又写了一个脚本把文本转化成HTML文件。然后又弄了一个根据正则匹配的脚本来帮助玩文字解密游戏。再然后通过管道计算出了各种莎士比亚基本的单词出现频率等。管道的神奇就不罗嗦了。
第六章变量、判断、重复动作
有两个相似命令提供变量的管理,一个是readonly,可以将变量设置为只读模式,就是成为符号常量。export用于修改或者打印环境变量。他们都由一个-p选项,意思是打印命令的名称以及所有被导出(只读)变量的名称和值,这种方式可使得shell重新读取输出以便重新建立环境(只读设置)。
export -p可以显示所有当前的环境变量,如果要从程序的环境中删除变量,则要用env命令,也可以临时的改变环境变量值:
env -i PATH=$PATH HOME=$HOME LC_ALL=C .....
-i选项用来初始化(initializes)环境变量的,也就是丢弃任何的继承值,仅传递命令行上指定的变量给程序使用。
unset命令从执行中的shell中删除变量和函数,默认情况下,它会解除变量设置,也可以加上-v完成:
unset full_name #删除full_name变量
unset -v firest middle last #删除多个变量
unset -f full_function #删除函数
这里我尝试用unset删除readonly变量,发现无法删除。然后查询了以下,发现常量声明之后就无法更改包括删除,只有注销当前shell。
有时候输出某个变量时,希望连接别的字符,可以在变量名左右添加花括号如:
echo _${myvar}_ #这样会输出myvar变量并在前后增加下划线。
这样叫做参数的展开。如果变量未定义,展开后是null。
还有一种替换运算符:
${varname:-word} #如果varname存在且非null,则返回其值,否则返回word。
${varname:=word} #如果varname存在且非null,则返回其值,否则设置它为word然后再返回其值。
${varname:?message} #如果varname存在且非null,则返回它的值,否则显示varname:message,并退出当前的命令或脚本,如果省略message会出现默认信息parameter null or net set。
${varname:+word} #如果varname存在且非null,则返回word,否则返回null。
以上每个运算符内的冒号(:)都是可选的。如果省略冒号,则将每个定义中的“存在且非null”部分改为“存在”,也就是说,运算符仅用于测试变量是否存在。
还有模式匹配运算符#:
${variable#pattern} #如果模式匹配于变量值的开头处,则删除匹配的最短部分,并返回剩下的部分。
${variable##pattern} #如果模式匹配于变量值的开头处,则删除匹配的最长部分,并返回剩下的部分。
${variable%pattern} #如果模式匹配于变量的结尾处,则删除匹配的最短部分,并返回剩下的部分。
${variable%%pattern} #如果模式匹配于变量值的结尾处,则删除匹配的最长部分,并返回剩下的部分。
最后,POSIX标

