UNIX编程环境(The UNIX Programming Environment) 备忘录(四)

第四章 过滤程序

 

grep/egrep/fgrep
fgrep  可同时搜索多个文字字符串
egrep  解释真正的正则表达式

-f  fgrep/egrep可通过该选项从指定的文件中读取模式

------------------------------------------
grep/egrep正则表达式
c  任何与自己匹配的非特殊字符
/c  去掉字符c的任何特殊意义
^  行首
$  行尾
.  任意单个字符
[...]  匹配...中的任一字符
[^...]  匹配未在...中出现的字符
/n  与第n个/(.../)匹配的字符(仅grep可用)
r*  匹配r零次或多次
r+  匹配r一次或多次(仅egrep)
r?  匹配r一次或零次(仅egrep)
xy  y紧随x
x|y  x或y(仅egrep)
/(r/)  带括号的正则表达式r(仅grep),可嵌套
(r)  正则表达式r(仅egrep),可嵌套


在BSD下,(r)不能直接使用,而"(c)"可用,意思同c,
而'(c)'的意思是匹配3个字符,包括两边的括号
==========================================
sort 
+n  按第n列排序,第一列n=0
-f  按字母表顺序排序,不区分大小写
-u  删除重复行

 

==========================================
comm  
显示结果的说明:
第一列: 第一个文件不同于第二个文件部分
第二列: 第二个文件不同于第一个文件部分
第三列: 两个文件相同的部分

-1  禁止显示第一列
-2  禁止显示第二列
-3  禁止显示第三列
上面三条可合并  

 

$$$$$$$$$$$$$$$$$$$$$$$$$$$$
无法解释的问题:

文件f1的内容:
abcd
efgh
ijkl

文件f2的内容:
abcd
kefgh
ijkl

但是结果竟然是这样:
$ comm f1 f2
                abcd
efgh
ijkl
        kefgh
        ijkl

我认为结果不该像上面,而应该是这个:
$ comm f1 f2
                abcd
efgh
        kefgh
         ijkl

可是假如f2的内容是:
abcd
efghk
ijkl

结果如我所想,显示如下:
$ comm f1 f2
                abcd
efgh
        efghk
                ijkl

==========================================
tr  转换字符

示例:
tr a-z A-Z 将输入中的所有小写转换为大写

==========================================
sed  stream editor


a /  将行添加到输出直至不以/终结的行
b 标号  转至命令 :标号
c /  对随后的文本,如同a命令那样逐行修改
d  删除行,读下一个输入行
i /  在下一个输出前插入下面的文本
l  按行列表,使所有的非打印字符可见
p  打印行
q  退出
r 文件  读文件,拷贝内容到输出
s/RegExp/str/f 用str替换RegExp,若f=g,置换所有变化;f=p,打印;f=w,写入文件  
t 标号  测试,若对当前行作了替换,转至标号  
w 文件  将行写到文件  
y/str1/str2/ 用str2中的对应字符替换str1中的每个字符(不支持范围值)
=  打印当前输入行号
! 命令  仅当行未被选取时,执行sed命令
: 标号  为b和t设置标号
{}  将{}之间的命令视为一组

 

SED单行脚本快速参考

http://sed.sourceforge.net/sed1line.txt
http://sed.sourceforge.net/sed1line_zh-CN.html


-n  关闭自动打印
sed -n '/模式/p' 这样只有匹配模式的行才被打印

n  把下一行的内容写到模式中,具体参见示例:
  sed 'n;d' 删除偶数行
  sed 'n;p'
  sed 'p;n'
  sed 'p;n;n'
  sed -n 'n;p'
  sed -n 'p;n'
  sed -n 'p;n;n'

 

 

关于Tab的输入:
如果是在命令行输入,可以按crtl+v再按crtl+i
如果是写成脚本执行,直接按TAB


多命令示例:
sed 's/^/ /
    3q'
作用:每行的行首加上Tab
      打印前3行后退出
注意:每条命令应放在单独的行,sed会忽略每行行首的空格和Tab


-f 命令文件 从命令文件中获取命令
示例:
fsed 写有sed命令的文件
 命令文件内容中只能有命令部分,即命令行下引号中的内容
file 要处理的文件
sed -f fsed file

 

实例:
$sed 's/$//
>    /'     #插入新行,注意上一行最后的反斜线

$sed 's/[ <Ctrl+v,Ctrl+i>][ <Ctrl+v,Ctrl+i>]*//
>    /g'    #用换行替换每行的空格或Tab,这样就可以变成每行一个单词

sed -n '20,30p'  打印20-30行
sed '1,10d'   删除1-10行
sed '1,/^$/d'  删除直至包括第一个空行
sed -n '/^$/,/^end/p' 打印从一个空行开始到end结束的行组
sed '$d'  删除最后一行


shell脚本  
ls -t |sed '/^'$1'$/q' 打印目录中比指定目录更新的文件
ls -tr|sed '/^'$1'$/q' 打印目录中比指定目录更旧的文件

==========================================
模式扫描与处理语言awk

$ awk '程序' 文件名

程序:
模式 {action}
...
模式 {action}


awk -f 命令文件 文件名

awk自动将输入行分段(空格、Tab)
这些字段可引用为$1,$2,...,$NF
NF为字段个数,本身也是一个变量

 

-F fs  指定fs作为分隔符
awk -F 分隔符 {action}


比较示例:
$2 == "" 第二个字段为空
$2 ~  /^$/ 第二个字段与空串匹配
$2 !~ /./ 第二个字段不与任何字符相匹配
length($2) == 0 第二个字段的长度为零


两个特殊模式: 
BEGIN {action} 在读入第一个输入行前执行
END   {action} 在处理完最后一行后执行


awk中的变量:
不用声明、变量缺省值为零


内部变量:
FILENAME 当前输入的文件名
FS  字段分隔字符
NF  输入记录中的字段个数
NR  输入记录数
OFMT  数字的输出格式(缺省为%g)
OFS  输出字段分隔符(缺省为空格)
ORS  输出记录分隔符(缺省为换行)
RS  输入记录分隔符(缺省为换行)


awk控制流:
可以使用if、for、while


可以使用关联数组


awk内嵌函数:
cos(表达式)  余弦
exp(表达式)  取自然指数
getline()  读入下一行,若文件结束,返回0,否则返回1
index(str1,str2) str1中str2的位置,若不存在,返回0
int(表达式)  取整,向0截取
length(str)  长度
log(表达式)  自然对数
sin(表达式)  正弦
split(str,a,c)  以c为分隔符将str分割成a[1]...a[n]并返回n
sprintf(格式,...) 格式化...
substr(str,m,n)  截取str中索引m开始的n个字符的子串

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值