以下工具的使用都是建立在会简单使用正则表达式的基础上,不了解的群攻自己做功课。
sed
sed是一种流式编辑器,是一种文本编辑工具,以行为单位进行文本操作。sed默认按照basic规则进行匹配。
常用的命令格式如下:
sed option ‘/pattern/action‘ file
pattern:为一个正则表达式,用来匹配所要操作的字符串行。
action:是操作方法。常用的操作方法有:
- p,将匹配到的内容打印两次,其他未匹配的打印一次。
- d,将匹配到的字符串删除。
- s,进行匹配字符替换。常用党的命令格式如下:
sed option ‘patter/s/patter1/patter2/g’ file
在patter匹配的字符串行中,用patter2替换patter1。加g选项是全部替换,不加g选项只替换第一个匹配到的。
- n,读取下一行到模式缓冲区中,将模式空间的原内容清空。
- N,读取文件的下一行追加到模式空间内,不请客原内容。
option:选项,对数据做的相应操作,常用的有:
- -n 将匹配到的字符串行输出,其他不输出。
- -i 将修改的内容同步修改到源文件。
- -e 多项编辑命令,可连接多个sed指令对同一行进行操作。
定址
定址用于决定对哪些行进行编辑。地址的表示可以由数字,正则表达式或者二者的结合。如果没有指定地址,sed将处理输入文件的每一行。
eg:
sed -n ‘3p’ file 打印文件第三行。
sed -n ‘100,200p’ file 打印文件第100行~200行的信息。
地址是逗号分隔的,需要处理的地址是这两行之间的范围(包括这两行在内)。范围可以用数组正则表达式或者二者的结合表示。
sed ‘2,5d’ file 删除第2行到底5行
sed ‘/start/,/end/d’ file 删除包含‘start’行和‘end’行之间的行。
sed ‘/start/,10d’ file
模式空间
sed对一个文件进行操作时,会依次将文件的每一行拷贝读取到一个特殊的缓冲区,也叫模式空间内,依次读取一行。读取完后进行正则表达式的匹配,若匹配,则进行action操作,若不匹配则丢弃。紧接着处理完后读取下一行。所以sed对文件行的操作是在模式空间内,不会对源文件进行修改。
保持空间
我们可以把保持空间想象成一个仓库,作为数据的暂存区域,但记住,处理数据时依然需要将数据由保持空间加载到模式空间。
保持空间并不常用,只有以下几条指令会用到保持空间。
g:将保持空间的内容拷贝到模式空间内,并将模式空间的原内容清除。
G:将保持空间的内容追加到模式空间内,不清除原内容。
h:将模式空间的内容拷贝到保持空间,将原来保持空间的内容清除。
H:将模式空间的内容追加到保持空间,不清除原内容。
d:删除模式空间的所有行,并读入下一新行到模式空间。
D:删除multiline pattern的第一行,不读入下一行。
x:交换保持空间与模式空间的内容。
eg:
①给文件的末尾加一个空行
②将文件逆序输出(模拟tac指令)
③将匹配的行追加到文件尾。
sed -e ‘/hello/H‘ -e ‘$G‘ file ###类似于复制功能
sed -e ‘/hello/{H;d}‘ -e ‘$G‘ file ## 类似于剪切功能
④行列转换
sed -n ‘H;{x;s/\n/ /g;p}‘ file
模式空间默认去掉每一行的\n,所以要想仅仅在模式空间内部将\n替换掉是行不通的, 保持空间内部有两行或两行以上内容时,会在每一行后面加上\n,所以现将数据Hold到保持空间,在执行x指令,进行模式空间与保持空间内容的交换,再进行替换。
⑤求1~100的和
seq 100|sed -n ‘H;${x;s/\n/+/g;s/^+//;p}‘|bc ### bc指令是对表达式求和。
s/^+// 表示将开头多余的加号替换为空。
⑥读取奇偶行
这里用到了n命令,读取下一行到模式空间。
sed -n ‘p;n‘ file ### 读取奇数行
sed -n ‘n;p‘ file ### 读取偶数行
标签
定义一个标签:
:a ### 定义标签规则为冒号加标签名,例标签名为a
跳转到标签:b+标签名
ba ### 跳转到标签a
再次实现1到100求和:
sed -n ‘:a;N;s/\n/+/g;{!ba};p‘ ####!ba 表示最后一行不跳转到标签a
N实现的是将下一行追加到模式空间的功能,如第一次执行语句是,将1读入模式空间,此时执行N将下一行追加到模式空间,此时模式空间的内容就变成1\n2,再进行+号的替换,依次类推,直到最后一行。
awk
awk既是一种文本分析工具,也是一种脚本语言。作为一种文本分析工具,它的功能比grep或者sed要强大的多,但它的用法与sed类似。作为一种脚本语言,它与c语言语法类似,有与c语言一样的分支和循环结构,是一种类c语言。
相对于sed来说,awk强大的地方在于它既可以以行为单位进行文本编辑,又可以以列为单位进行文本编辑。awk默认的缺省的行分隔符为换行\n,默认的列分隔符为连续的空格或者tab。比如下图:
除了以空格和tab作为分隔符外,还可以自定义分隔符,如下图用冒号做分隔符。
当以列为单位时,$0表示整行的内容,$1表示第一列…$n表示第n列。
awk命令行的格式:
awk option ‘/pattern/{action}‘ file
awk option -f scriptfile file ### 用 -f 指定脚本文件
pattern为正则表达式,用于匹配要操作的行。action为要执行的动作。
这里要说一个-F选项,-F选项可以指定输入域分隔符,当我们在文件内使用自己指定的分隔符时,默认的awk指令是识别不了的,我们需要用-F选项指定出我们需要辨识的分隔符。如我们在上面用的分隔符是冒号‘:’,下面我要打印第二列的内容:
awk ‘{print $2;}‘ file ### 失败,系统无法辨识分隔符。
-F:
awk -F: ‘{print $2;}‘ file ### 成功,指定分隔符为:
正则表达式
利用正则表达式进行行匹配:
①找出productC的行的内容:
②查找编号为2(第三列,以2结尾)的内容:
指定域进行正则表达式匹配。~与!~
可以用~指定固定的域(列)进行正则匹配。!~与~!相同。与if语句搭配使用。
①找出第二列中以1开头的数据行。
awk -F: ‘{if($2 ~ /^1/){print $0;}}‘ file
②找出第二列中不以1开头的数据行。
awk -F: ‘{if ($2 !~ /^1/){print $0}}‘ file
条件匹配
除了用正则表达式进行行匹配外,还可以进行条件匹配,命令格式如下:
awk option ‘condition{action}‘ file
如:将第二列的值小于100的都标记为NO,其他标记为YES。
awk -F: ‘$2<100{print $0,"NO";}$2>100{print $0,"YES";}‘ file
注意{}里面的写法,逗号‘,’作为输出域分隔符,在输出时被转化为空格。
BEFIN和END
要理解BEGIN和END,先要理解awk执行的三个过程,分别为,文本处理之前,文本处理中,文本处理之后。
BEGIN就是文本处理之前执行的动作,END就是文本处理之后执行的动作。
eg:利用BEGIN和END计算行数。
awk -F: ‘BEGIN{x=0}{print $0;x++}END{print "total:",}‘
BEGIN,END可单独使用可搭配使用。如下:单独使用END输出行号。
我们在上面说过,awk也是一种类c语言,是一种弱类型语言,它的变量不需要定义,可直接使用,下例中x默认初值为 0。
awk脚本
awk除了上述以命令行方式使用外,还可以以shell脚本的方式使用。因为awk也是一种脚本语言,所以awk有有自己的命令解释器,/bin/awk或者/bin/awk -f。
test.awk:
#!/bin/awk -f
BEGIN{
count1=0; //注意变量的定义格式
count2=0;
count3=0;
total=0;
}
{
print $0;
if($2 < 100){
count1++;
}else if($2 >= 100 && $2 < 200){
count2++;
}else if($2 >= 200){
count3++;
}total++;
}
END{
printf("<100: %d\n",count1); ### 类c语言,可直接使用printf。
printf(">=100 && < 200: %d\n",count2);
printf(">=200: %d\n",count3);
printf("total: %d\n",total);
}
awk脚本文件的调用格式为:
awk [-F+分隔符] -f awkfile file
例:
awk -F: -f test.awk file
执行结果为:
awk的内置变量
ARGC 命令行参数的个数
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件中的记录数(行数)
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
printf与print
awk是类c语言,所以在脚本程序或者命令行都可以使用printf。有时使用printf可以使输出格式变得更加工整。
eg:
awk -F: ‘{printf("filename:%s count:%d data:%s\n",FILENAME,FNR,$0)}‘ file
结果:
[[email protected] ~]$ awk -F: ‘{printf("filename:%s count:%d data:%s\n",FILENAME,FNR,$0)}‘ file
filename:file count:1 data:productA:123:1
filename:file count:2 data:productB:22:2
filename:file count:3 data:productC:23:3
filename:file count:4 data:productD:3:4
filename:file count:5 data:productE:223:5
练习:统计目录下普通文件所占用的字节数
ls -lR | grep -E ‘^-‘| awk ‘{print $9,$5;total+=$5}END{print total}‘
结果:
除此之外,还可以用find指令来查找对应大小的文件,但无法求和。
find . -size +100c -a -size -1000c -exec ls -l {} \;
cut
cut的功能是‘剪’,以行为单位进行文本处理。命令格式如下:
选项主要有三个:
-b:按照字节进行切割。
-c:按字符进行切割
-b与-c的区别在于,-b无法剪切中文,而一个中文也算一个字符,所以-c可以剪切中文。相对于英文字符来说,它们两个功能相同。
-f 按域进行剪切。与-d搭配使用,-d指定分隔符,-f指定域。
sort
sort的功能是对指定的文件按照一定的规则进行排序。格式为:
sort option file
1、单独使用sort默认以字符的ACCIS码的值进行排序。
2、-u ,按照字符ACCIS码以升序排序,并去掉重复的行。
3、-r ,逆序排序
4、sort file -o file ,排序并修改源文件。
5、-n 按照数值大小进行排序。
6、按照指定的列进行排序,-t 指定分隔符,-k指定列数。
7、-f,将小写字母转换为大写字母进行比较,即忽略大小写。
8、-c 检测文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1。
9、检查文件是否已排好序,如果乱序,不输出内容,仅返回1。
10,-M 按照月份来排序
11、-b,忽略每一行前面的空白部分,从第一个可见字符开始比较。
eg:
[lzk@localhost ~]$ cat file
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
1、按照第二列人数进行排序。
[lzk@localhost ~]$ sort -t‘ ‘ -k 2n file
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
2、按照人数排序,当人数相同时,按照第三列工资进行排序。
[lzk@localhost ~]$ sort -t‘ ‘ -k 2n -k 3n file
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
3、按照公司名称第二个字母开始往后进行比较(即按照第一个域的第2个字母直到本域结束)
[lzk@localhost ~]$ sort -t‘ ‘ -k 1.2 file
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
4、仅按照公司名称的第二个字母进行排序,如果相同,按照员工人数进行排序。
因为仅按照第一列的第二个字母进行排序,所以用1.2,1.2的方式表示,2,2表示只按照第2个域进行排序,如果只写一个2,则表示按照第2个域到最后一个域进行排序。
[lzk@localhost ~]$ sort -t‘ ‘ -k 1.2,1.2 -k 2,2n file
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
uniq
这个命令读取输入文件,并比较相邻的行,在正常情况下,第二个以后以后更多个重复的行将被山区,行比较是根据所用字符集的排序序列进行的。该命令加工后的结果写到输出文件中。输入文件和输出文件必须统统。如果输入文件用‘-’表示,则从标准输入读取。
常用的选项如下:
-c:去掉连续的重复行,并在每行行首加上本行重复出现的此时。可以取代-u或者-d选项。
-d:只显示重复行。
-u:只显示文件中不重复的行。