awk
awk在对其数据分析并产生报告时显得尤为强大。
awk就是把文件逐行读入,按照(空格和制表符)默认分隔符将每行进行切片,切开的部分在进行各种操作.
格式:
awk -F '{pattern+action}' {filenames}
— 支持自定义分隔符
— 支持正则表达式匹配
— 支持自定义变量,数组s[1],s[tom],map(key)
— 支持内置变量
属性 | 说明 |
---|---|
$0 | 当前记录(作为单个变量) |
1 1~ 1 n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格 |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始 |
RS | 输入的记录他隔符默 认为换行符 |
OFS | 输出字段分隔符 默认也是空格 |
ORS输出的记录分隔符,默认为换行符 | |
ARGC | 命令行参数个数 |
ARGV | 命令行参数数组FILENAME当前输入文件的名字 |
— 支持函数
print、split、substr、sub、gsub
— 支持流程控制语句,类C语言
if、while、do/while、for、break、continue
例子:
1、只是显示/etc/passwd的账户:CUT
awk -F ':' '{pint $1}' passwd
2、只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行开始前添加列名name,shell,在最后一行添加“blue,/bin/nosh”(cut,sed)
awk -F ':' 'BEGIN{print "blue,shell"}{print $1 "," $7} END{print "blue,/bin/nosh"}' passwd
3、搜索/etc/passwd有root关键字的所有行
awk '/root/ {print $0}' passwd
4、统计/etc/passwd文件中,每行的行号,每行的列数,对应的完整的内容。
awk -F ':' '{print NR "\t" NF "\t" $0}' passwd
5、报表分析统计:
步骤:
(1)编辑awk.txt文件:
(2)
awk '{split($3,date,"-");if(date[2]=="01"){name[$1]+=$5};if($2=="0"){role[$1]="manager"}else{role[$1]="worker"}}END(for i in name){print i "\t" role[i] "\t" name[i]}}' awk.txt
(3)整理成文件awk.sh
(4)执行
awk -f awk.sh
grep
grep是一种强大的文本搜索工具,他和find命令的主要区别就是:find是搜索文件/目录本身,也就是说我们在一个大目录里找子目录或在大目录里的文件,而grep命令呢?它不是找文件/目录本身,它是在搜索在文件里边的内容。
grep的工作方式:它在一个或多个文件中搜索与字符串模板(正则表达式)匹配的内容。如果模板包括空格,则必须打引号,模板后的所有字符串被看作文件名。搜索的结果被送到标准输出,不影响源文件内容。
grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功则返回1.如果搜索的文件不存在,则返回2,我们利用这些返回值就可以进行一些自动化的文本处理工作。
命令格式:
grep [option] pattern file
常用命令参数:
-E:开启扩展(Extend)的正则表达式。
-i:忽略大小写(ignore case)
-v:反过来(invert),只打印没有匹配的,而匹配的反而不打印。
-n:显示行号
-w:被匹配的文本只能是单词,而不能是单词中的某一部分,如文本中有liker,而我搜寻的只是like,就可以使用-w来避免匹配liker。
-c:显示总共有多少行被匹配了,而不是显示被匹配到的内容,注意如果同时使用-cv选项是显示有多少行没有被匹配到。
-o:只显示被模式匹配到的字符串。
--color:将匹配到的内容以颜色高亮显示。
-A n:显示匹配到的字符串所在行及其后n行,after
-B n:显示匹配到的字符串所在行及其前n行,before
-C n:显示匹配到的字符串所在行及其前后各n行。
例子:
(1)找文件中包含"abc"这三个字符的内容行
grep "abc" ./grepdemo.txt
fgrep "abc" ./grepdemo.txt #查找速度快
(2)查询结果忽略大小写
grep -i "abc" ./grepdemo.txt
基本正则表达式:
符号 | 含义 | 示例 |
---|---|---|
. | 任意一个字符 | grep “abc.” ./grepdemo.txt |
[abc] | 表示匹配一个字符,这个字符必须是abc中的一个,区2个字母中分大小写 | grep “[abc]” ./grepdemo.txt |
[a-zA-Z] | 表示匹配一个字符,这个字符必须是a-z或A-Z这52个字母中的一个 | grep “[0-9]” ./grepdemo.txt |
[^123] | 匹配一个字符,这个字符是除了1,2,3以外的所有字符 | grep “abc[^A-Za-z]” ./grepdemo.txt #abc123 |
匹配次数:
{m,n} | 匹配其前面出现的字符至少m次,至多n次 |
---|---|
? | 匹配其前面出现的内容0次或1次,等价于{0,1} |
* | 匹配其前面出现的内容0次或多次,匹配其前面出现的内容任意次,等价于{0,},所以".*"表述任意字符任意次,即无论什么内容都能匹配 |
注意:默认情况下,正则表达式的匹配工作是在贪婪模式下,也就是说它会尽可能长的去匹配,所以当匹配规则为 "/.*sh"时,他不会匹配/bash,而是匹配/root:/bin/bash。
例子:
搜索/etc/passwd文件中以/开始,以sh结尾的字符串,在/和sh中间可能有0-2个任意字符
grep "/.\{0,2\}sh" /etc/passwd
位置锚定:
符号 | 含义 | 示例 |
---|---|---|
^ | 锚定行首。注意:[ ^ ]表示取反,^用在括号外面表示行首 | grep “^root” /etc/passwd |
$ | 锚定行尾。"^$"用于匹配空白行 | grep “h$” /etc/passwd |
\b或< | 表示单词的词首。如"\blike"不会匹配alike,但是会匹配liker | grep “<sh” /etc/passwd #找到所有以sh开头的单词 |
\b或> | 表示单词的词尾。如·"\blike\b"不会匹配alike和liker,只会匹配like | grep ‘sh>“ /etc/passwd |
\B | 与\b作用相反。如"\Bsh\B",找sh,但是不能在单词的开头也不能在单词的结尾。 | grep “\Bsh\B” /etc/passwd |
分组及引用:
扩展正则表达式:
例子:
在网络配置文件/etc/sysconfig/network-scripts/ifcfg-ens33中检索出所有ip
egrep "/<([1-9][0-9]?[0-9]?\.){3,3}[1-9][0-9]?[0-9]?" /etc/sysconfig/network-scripts/ifcfg-ens33
sed
流编辑器,对标准输出或文件逐行处理。
用法:
stdout | sed [option] "pattern command" #pattern指匹配,command指执行操作
sed [option] "pattern command" file
sed的选项:
选项 | 含义 |
---|---|
-n | 只打印模式匹配行 |
-e | 直接在命令行进行sed编辑默认选项 |
-f | 编辑动作保存在文件中,指定文件执行 |
-r | 支持扩展正则表达式 |
-i | 直接修改文件内容 |
基本命令command:
(1)对文本中的每一行执行输出
sed 'p' sed.txt
每行输出两边,sed默认输出原行,并输出模式匹配行,使用如下命令避免:
sed -n 'p' sed.txt
(2)打印匹配到python的行
sed -n '/python/p' sed.txt
(3)同时有多个编辑命令时使用-e
sed -n -e '/python/p' -e '/PYTHON/p' sed.txt
(4)把编辑命令保存在文件中,在匹配时使用-f调用文件
vim edit.sed
/python/p
命令行执行:
sed -n -f edit.sed sed.txt
(5)想使用一个命令打印两种限制(简写版-e)
sed -n -r '/python|PYTHON/p' sed.txt
(6)修改单词并输出
sed -n 's/love/like/g;p' sed.txt
注意:不修改原文件,若要修改原文件,加-i
sed -i 's/love/like/g' sed.txt
pattern详解:
示例:
(1)直接指定行号
sed -n "17p" file
(2)指定起始行号和结束行号
sed -n "10,20p"file
(3)正则表达式匹配的行
sed -n "/^root/p" file
(4)从pattern1匹配的行开始,直到指定行结束
sed -n "/root/,10p" file
注意:如果/root/所在行在第10行之后,则只会打印/root/匹配行内容,不输出第10行。
编辑命令:
修改:
s/pattern/string/2 | 表示同一行内只替换第二个字符串 |
---|---|
s/pattern/string/2g | 表示同一行内,从第2个开始到剩下所有的替换。 |
示例:
(1)删除文件第一行
sed -i '1d' passwd
(2)删除不可登录的用户
sed -i '/\/sbin\/nologin/d' passwd
(3)匹配到的行后添加内容
sed -i '/\/bin\/bash/a This is user' passwd
(4)匹配到的每一行,行前追加
sed -i '/^hdfs/,/^yarn/i This is user' passwd
(5)将文件list内容全部追加到含root字符串的行的行后
sed -i '/root/r list' passwd
(6)将文件中含有’/bin/bash’的行全部写入/tmp/user_login.txt文件
sed '/\/bin\/bash/w /tmp/user_login.txt' passwd
(7)显示符合条件内容的行号,不显示内容
sed -n '/\/sbin\/nologin/=' passwd
(8)反向引用
sed -i 's/had..p/&s/g' str.txt
sed -i 's/\(had..p\)/\1s/g' str.txt
注意:\1更加灵活,可以替换部分
sed -i 's/\(had\)...../\1doop/g' str.txt
sed中引用变量时注意事项:
(1)匹配模式中存在变量,则建议使用双引号
(2)sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号
例如:
例题:
对应脚本:
修改命令:
find
whereis命令:whereis是搜索系统命令的命令,也就是说,whereis命令不能搜索普通文件,而只能搜索系统命令。作用:能够超除命令的二进制源文件的位置和帮助文档的位置。
which命令:也是搜索系统命令的命令,和whereis命令的区别在于他们的显示结果不同。
which命令的作用:二进制命令的位置,如果这个命令有别名,则还可以显示别名。
find命令:因为Linux下面一切皆文件,经常需要搜索某些文件来配置,所以对于linux来说find是一条很重要的命令。linux下面的find指令用于在目录结构中搜索文件,并执行指定的操作。它提供了相当多的查找条件,功能强大,在不指定查找目录的情况下,find会在对整个系统进行遍历。缺点:耗时。
命令格式:
find [查找目录] [查找规则] [查找完后的操作]
例子:
(1)通过文件名字查找,如名字为test的文件或目录,这个是精准查找
find ./ -name test
(2)加通配符,查找名字包含test的文件或目录,这个是模糊查找
* 表示任意字符 ? 表示一个字符
find ./ -name *test*
find ./ -i name *test*
(3)查询文件大小大于10M的文件
find ./ -size +204800
注意:这里的单位是数据块,它和k的换算:1数据块=215字节=0.5k 所有100M=10240K=204800(数据块)
+表示大于
-表示小于
不写表示等于
(4)查询所有者为xxx的所拥有文件
find / -user xxx
(5)查询所有组为xxx的所拥有文件
find / -group xxx
(6)查询在etc目录下5分钟内被修改过文件属性的文件和目录。
find /etc -cmin -5
- amin:表示被访问
- cmin:表示属性被修改
- mmin:表示内容被修改
(7)多条件查询,在/etc目录下查找文件大小大于80M,并且小于100的文件
find /etc -size +163840 -a -size -204800
-a:表示and,并且关系
-o:表示or,或者关系
(8)默认查找的内容是目录和文件,但是我们只想找到文件或目录中的一个,如:查找/etc目录下的init开头的文件
find /etc -name init* -a -type f
(9)查找文件后,进一步执行一些命令:如查找文件后显示详细属性信息
find /etc -name init* -exec ls -l {} \;
{} \ ;:后面这三个符号当作一个固定结构,其中"{}"就代表find命令的查找结果。注意:-exec可以替换-ok,功能一样,只是多一个提示。
(10)通过inode号来处理文件
ll -i #查看文件inode
find ./ -inum 16800618 -exec rm -fr {} \;
locate
locate命令 用来查找文件,在这点上和find命令一样,locate命令要比find -name快得多,原因在于它不搜索具体目录,而是搜索一个数据库/var/lib/miocate/miocate.db,这个数据库中含有本地所有文件信息,Linux系统自动创建这个数据库,并且每天自动更新一次。因此,我们在用locate查找文件时,有时会找到已经被删除的数据,或者刚刚建立文件,却无法查找,原因就是因为数据库文件没有被更新,为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。
用法:
locate [选项]...[参数]...
-i:忽略大小写
使用:
1、安装"locate"命令,运行yum install mlocate
2、mlocate已经安装完成,接下来需要更新后台数据库,输入updatedb
3、使用locate。
示例:
(1)搜索etc目录下所有以my开头的文件
locate /etc/my
注意:find /etc/ -name my* 会查找该目录下以及其子目录中所以以my开头的文件
(2)新增文件需要updatedb
touch aaa.txt
locat /root/a #未找到
updatedb
locate /root/a #找到了
updatedb配置文件/etc/updatedb.conf