linux四剑客-grep/find/sed/awk/详解-技术流ken
四剑客简介
相信接触过linux的大家应该都学过或者听过四剑客,即sed,grep,find,awk,有人对其望而生畏,有人对其爱不释手。参数太多,变化形式太多,使用超级灵活,让一部分人难以适从继而望而生畏,浅尝辄止即罢。有人熟练掌握,使其四剑客为己所用,在分析日志,分析文本,统计,批量修改中游刃有余,大大提高了工作效率。本篇博文将详细讲解四剑客的参数选项,以及使用案例,相信认真读完本篇博文你也可以使得四剑客真正为己所用。
四剑客之grep
1.几个概念
正则表达式:Regular Expression
作用:用一些特殊的字符来描述一个模式
字符:
普通字符:0-9 a-z A-Z
特殊字符(元字符):* . {} |
正则和通配符
正则是用于对文件中的内容进行过滤和匹配
通配符用于对文件名进行匹配
2.grep命令选项
作用:用于对文件中的内容进行过滤
原理:逐行对文件中的内容根据样式进行匹配,如果匹配成功就过滤出该行
格式:grep [options] PATTERN file
PATTERN:要匹配的模式
options:
-i:忽略文件中的内容的大小写
-o:仅仅显示所匹配到的内容(不显示整行)
-v:取反,用于获取不包含指定内容的行
--color:将匹配到的内容进行着色
-A num:在匹配到指定的行以后,额外显示下面的num行
-B num:在匹配到指定的行以后,额外显示上面的num行
-C num:在匹配到指定的行以后,额外显示上下各num行
正则表达式的特殊符号
. 表示任意一个字符 [] 表示范围内的一个字符 [^] 表示匹配范围以外的任意一个字符 * 表示其前面的字符出现任意次数(0,1,n)的情况(注意是匹配*前面的字符,比如*前面是5. 5*就表示匹配一个5或者0个或者n个5) .* 表示任意长度的任意字符 ? 表示其前面的字符出现最多一次的情况 \{m,n\} 表示其前面的字符出现最少m次,最多n次的情况 ^ 匹配行首 $ 匹配行尾 \< 锚定单词首部 \> 锚定单词尾部 \(分组\) \1 调用前面的第一个分组 \2 调用前面的第二个分组
扩展正则表达式
grep -E
egrep
扩展正则表达式多了一个+号和一个或者|的符号而已
三剑客之grep案例
例子:显示出a.txt中不包含字母 c 的行
[root@ken ~]# grep -v "c" a.txt
例子:统计a.txt中包含字母q的行的数量
[root@ken ~]# grep "q" a.txt | wc -l
例子:过滤出包含大写字母的行
[root@ken ~]# grep "[A-Z]" a.txt
例子:匹配非数字字符
[root@ken ~]# grep "[^0-9]" a.txt
例子:查看包含字母a的行,要求显示该行上下各5行
[root@ken ~]# grep --color -C 5 "a" a.txt
例子:过滤出一行中a在前,b在后的行
[root@ken ~]# grep --color "a.*b" b.txt
例子:匹配a和b之间有最少2个c最多5个c的行
[root@ken ~]# grep "ac\{2,5\}b" a.txt
例子:过滤出以# 为开头,且第二个字符是空格的行
[root@ken ~]# grep "^#[[:space:]]" a.txt
例子:过滤出行首和行位字母相同的行
[root@ken ~]# grep "^\([a-z]\).*\1$" a.txt
例子:过滤出第一个字符是#,且第二个字符串是非空字符,而且结尾是数字的行
[root@ken ~]# grep --color "^#[^[:space:]].*[0-9]$" a.txt
四剑客之find
1.简单介绍
特点:
查找速度相对慢
准确率高,而且可以根据文件的多种特性进行查找
原理:
find会在指定目录及其子目录中进行逐级查找
格式:
find [options] [路径] [查找条件] [执行的动作]
说明
路径:就是在哪个目录下进行查找
可以是绝对路径,也可以是相对路径
2.find的查找条件
-name 可以使用通配符 -iname忽略大小写 -groupname -username -gid -uid -nogroup 无属组 -nouser 无用户 -size 文件大小 -type 文件类型 -mtime 创建时间 -ctime 修改时间 -atime 访问时间 -perm 后面跟的权限 -exec find xxx -exec 命令 \;
组合条件(-a,-o,-not)
3.三剑客之find案列
例子:从当前位置下找出后缀是txt的文件和目录
[root@ken ~]# find ./ -name "*.txt"
例子:找文件的属主是 py22 的文件和目录
[root@ken ~]# find / -user "py22"
例子:找文件大小是1M的文件
[root@ken ~]# find / -size 1M
说明:
查找找结果是<=1M的文件
-size [+-]n
+:大于指定的值
-:小于指定的值
例子:找文件大小大于1G的文件
[root@ken ~]# find / -size +1G
例子:找一般文件
[root@ken ~]# find / -type f
例子:从/tmp下找出后缀是wps 或doc 或exel的文件
[root@ken ~]# ind /tmp/ -name *.doc -o -name *.exel -o -name *.wps
例子:找出系统中全部用户都有执行的权限的文件
[root@ken ~]# find / -perm -111
-perm权限前面没有任何符号表示精确查找,比如查找666,查找出来的文件权限必须是666权限
-perm权限前面有/表示模糊查找,9个权限包含一个即可
-perm权限面前有-表示必须包含所指定的权限
例子:将tmp下有执行权限的文件中的执行权限去除
[root@ken ~]# find /tmp -perm /111 -exec chmod a-x {} \;
四剑客之awk
在说awk之前首先介绍几个小命令
1.几个小命令
cut命令
cut命令 作用:根据指定的分隔符来切割数据,然后显示指定的部分 选项 -d'字符':指定分隔符 -f#:指定显示分割后的那一部分数据 输出的情况 1)输出一段:指定一个编号 2 2)输出连续多段:编号-编号 2-5 3)输出不连续多段:编号,编号... 2,3,5 # echo "bin:10:15:i am bin:/home/bin:/sbin/nologin" 例子:输出上面的15 # echo "bin:10:15:i am bin:/home/bin:/sbin/nologin" | cut -d':' -f3 例子:输出系统中全部用户的用户名和shell类型 # cat /etc/passwd | cut -d":" -f1,7
sort命令
sort命令 作用:按字符进行比较和排序 格式:sort 选项 file 选项: -t:指定分隔符 -k:根据切割后的那一段进行排序[根据切割后的那一段排序,不是取出来那一段] -n:表示根据数字进行排序(默认是根据字符进行排序) -f:忽略要比较的字符大小写 -u:去除重复的行(只要那个指定的字段重复,就认定是重复的行) -r:按照降序排序 例子:对文件中的内容进行排序 # sort mypwd (默认排序:针对每行的第一个字母的ASCII中的值进行比较排序) 例子:对文件中的内容按照冒号分割第二部分进行排序 # sort -t":" -k2
uniq命令
uniq命令[通常结合sort先进行排序,然后再使用该命令统计相同的行出现的次数] 作用:去除重复的行(相邻且相同,认定为重复) 选项: -c:在行首用数字表示该行出现了多少次 -d:仅仅显示出现过重复的行 -u:仅仅显示那些没有出现重复过的行 例子:将文件中相同的行去重 # sort mypwd | uniq
2.awk命令
作用:逐行处理文件中的内容(读取一行,处理一行)
例子:输出用户的uid
# cat /etc/passwd | awk -F ":" '{prin t $3}'
处理过程
1)前面的cat将内容传递给awk
2)awk读取一行,然后执行-F进行分割,然后执行一次{ }
格式:
awk [options] '[pattern]{action}' fileName
说明
options:选项,比如 -F 指定分隔符
pattern:输出的条件,比如仅仅输出以#开头的行
action:按照选项切换,并且是符合条件的行,要执行的操作或者命令,比如输出
概念:
记录(record):一行就是一个记录
分隔符(field separator):进行对记录进行切割的时候所使用的字符
字段(field):将一条记录分割成的每一段
3.常用的内置变量
FILENAME:当前处理文件的文件名 FS(Field Separator):字段分隔符(默认是以空格为分隔符) NR(Number of Rrecord):记录的编号(awk每读取一行,NR就加1) NF(Number of Field):字段数量(记录了当前这条记录包含多少个字段) ORS(Output Record Separator):指定输出记录分隔符(指定在输出结果中记录末尾是什么,默认是\n,也就是换行)[\n表示换行] OFS(Output Field Separator):输出字段分隔符 RS:记录分隔符
4.awk常用使用方式总结
结合本人平时使用总结可如下五种平时最常用的方式
1.结合内置变量,打印指定的几行,以及字段数量
例子:输出有多余5个字段的行的第三个字段
# cat a.sh | awk -F ":" 'NF>=5{print $3}'
例子:输出每行行号和该行有几个字段
# cat a.sh | awk -F ":" '{print NR,NF}'
例子:输出用户名,要求所有用户显示在同一行,而且用空格分隔
# cat mypwd | awk 'BEGIN{FS=":"; ORS=" "}{print $1}'
2.结合正则来匹配一行或者某个字段
例子:输出用户名以s为开头的用户的uid
# cat mypwd | awk -F ":" '/^s/{print $}'
例子:输出第五个字段是以t为结尾的用户的姓名
# cat mypwd | awk -F ":" '$5~/t$/{print $1}'
3.采用比较符号来进行打印指定的某些行
# cat mypwd | awk 'NR>=3&&NR<=5{print NR,$1}'
或
# cat mypwd | awk 'NR==3,NR==5{print NR,$1}'
例子:实现仅仅输出3 和 5 和 7行的内容,每行前面添加一个行号
# cat mypwd | awk 'NR==3||NR==5||NR==7{print NR,$1}'
4.结合BEGIN和END模块统计和N++等计算某些字段和行出现的次数
例子:统计mypwd中以#开头的行有多少行
# cat mypwd | awk 'BEGIN{n=0}/^#/{n+=1}END{print n}'
统计:mypwd中,以:为分隔符,字段数量在3-5的行的数目
# cat mypwd | awk 'BEGIN{FS=":"}NF>=3&&NF<=5{n+=1}END{print n}'
5.数组。定义一个数组采用 {ip[$3]++}END{for (i in 数组名ip)print i,ip[i]}
例子:统计IP
[root@centos6-2 tmp]# cat url.txt | awk -F "/+" '{urls[$2]++}END{for(key in urls)print key, urls[key]}’
四剑客之sed
1.简介
文本编辑器,也是对文件中的内容进行逐行的处理(一次处理一行)
sed的工作原理
sed读取一行,首先将这行放入到缓存中
然后,才对这行进行处理
处理完成以后,将缓冲区的内容发送到终端
存储sed读取到的内容的缓存区空间称之为:模式空间(Pattern Space)
格式:sed [options] file
2.选项
-p:打印输出(会将模式空间中的内容连同处理的行的结果一并输出)[Print 使用该选项后不要和-i一起使用,否则文本内容会被替换为只有指定的那些行 如果需要验证的话只需要使用-p和-n进行验证即可,不要加上-i -n和-i也不要一起使用] n:使用静默模式(不输出模式空间中的内容)[可以理解为no模式空间]
-r:使用扩招正则表达式中的符号[正则regular] -i:直接修改原始文件(默认是修改模式空间中的文件副本)[In place直接在文件里面修改] !:对命令的执行结果取反(不显示命令找到的内容)[和awk一样使用单引号]
&:引用前面的搜索结果
3.操作
a:添加
i:插入
d:删除
p:打印输出
s:字符串替换
c:做行替换
r: 从一个文件中读取到另一个文件中
w: 从一个文件中将匹配的内容写入到另外一个文件中
4.sed用法总结
结合本人使用,总结了如下sed常用用法
1.查找指定的字符串
例子:显示/etc/passwd中保含root的行(显示模式空间中的内容)
方法1:set '/root/p' /etc/passwd
方法2:cat /etc/passwd | sed '/root/p'
2.在指定的位置做增删
例子:删除以root为开头的行
# sed '/^root/d' a.txt
例子:在包含root的行后添加一行 i am zxhk
# sed '/root/a i am zxhk' a.txt
3.按行替换
例子:将5到9行的内容替换为 i am zxhk
# sed '5,9c i am zxhk' a.txt
4.按照字符替换
例子:将/etc/selinux/config中的SELINUX=enforcing改成 disabled
写法1:# sed -i 's/SELINUX=disabled/SELINUX=enforcing/g' config
写法2:# sed -r -i 's/(SELINUX=)disabled/\1enforcing/g' config
5.查找指定的内容再做替换
例子:将以r开头的行中的oo替换为qq
# sed '/^r/{s/oo/qq/g}' passwd
6.多点编辑
例子:去除文件中的注释行和空白行
# grep -v -E "(^#)|(^$)" passwd.bak >passwd
# cat passwd.bak | sed -e '/^#/d' -e '/^$/d' >passwd
7.取反操作
显示非1-3行
# sed -n '1-3!p' passwd