find、grep、sed、awk的使用

887 阅读5分钟

find

find主要用来文件搜索

常用搜索

find . -type f                          遍历log文件夹列出所有的文件
find . -max-depth 2                     搜索目录深度不高于2级
find . -min-depth 2                     搜索目录深度不低于2级
find . -name '*.log'                    文件名匹配,实现支持通配符的精确匹配
     . -iname "*.LOG"                   -iname忽略大小写
find . -path '*m*/.log'                 路径匹配,相比于-name搜索更模糊一些
     . -ipath                           -ipath忽略大小写
find . -size +10M                       查询大小超过10M的目录或文件,-10M则相反
find . -ctime +3                        查询文件属性更改时间超过3天的目录或文件,单位为天,-3效果相反
                                        访问时间(atime:access time),创建时间(mtime:modlfy time)
find . -cmin +3                         查询文件属性更改时间超过3分的目录或文件,单位为分钟,-3效果相反
                                        访问时间(amin:access time),创建时间(mmin:modlfy time)
find . -user root                       查询所属用户,-group查询所属组
find . -perm 755                        查询权限为755的文件或目录
find . -empty                           查询目录下所有的空文件

正则匹配

find . -name "[a-z].log"                匹配目录下[]内单个字符以.log结尾的文件,a-z表示a,b,c,d...z
find . -name "[a,b,d].log"              匹配目录下[]中的单个字符以.log结尾的文件
find . -name "a.log" -o -perm 644       匹配目录下“a.log”或权限为644的目录。
                                        -o为或    -a 为 并且    ! 为 反
find . -empty -type f -exec rm -f {} \; 查询当前目录下的空文件并且删除
find . -empty -type f -ok rm -f {} \;   每次删除前用户交互确认
find . -empty -type f|xargs rm -f       查询当前目录下的空文件并且删除
find . / -type f -printf "%f\n"         获取相对路径的basename
a.log
b.log
c.log
d.log
find . / -type f ! -path ./a.log        搜索结果中去除a.log这一项

grep

grep会对文本或多个正则表达式进行匹配,只输出匹配(或不匹配)的行或者文本,主要用于查找

主要参数

-i                                      忽略大小写
-c                                      显示符合匹配行的行数
-n                                      显示匹配行和行号
-v                                      反转匹配,显示不匹配的文本
-s                                      忽略文件不存在的错误信息
-r                                      递归目录查询匹配的字符
-l                                      只显示包含匹配的文件名
-A x                                    显示匹配行下x行
-B x                                    显示匹配行上x行
-C x                                    显示匹配行上下x行
-o                                      只显示匹配文本,每匹配一次显示一行。和wc -l搭配用于统计匹配单词的次数
-P                                      使用Perl正则

正则表达式元字符

^                                       锚定行首
\<或\b                                  锚定词首
$                                       锚定行尾
\>或\b                                  锚定词尾
.                                       匹配任意一个字符
*                                       匹配零个或多个前面的字符
\?                                      匹配前面字符0次或1次
\+                                      匹配前面字符1次或者多次
\{n\}                                   匹配前面字符n次
\{m,n\}                                 匹配前面字符至少m次,至多n次
[]                                      匹配一个指定范围内的字符
[^]                                     匹配指定范围外的任意单个字符
[[:digit:]]                             匹配任意单个数字
[[:lower:]]                             匹配任意单个小写字母
[[:upper:]]                             匹配任意单个大写字母
[[:alpha:]]                             匹配任意单个字母
[[:alnum:]]                             匹配任意单个字母或数字
[[:punct:]]                             匹配任意单个符号
[[:space:]]                             匹配单个空格

sed

主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。主要用于编辑

参数说明

-i                                      直接修改文件内容
-n                                      屏蔽默认输出
-r                                      启用扩展的正则表达式,若与其它选项一起使用,应作为首个选项
-{}                                     可组合多个命令,以,分隔

处理动作

p                                       打印行
d                                       删除行
s                                       替换字符串
g                                       全局替换
N                                       打印下一行
!                                      非,表示取反
=                                       打印行号
I                                       忽略大小写
&                                       表示匹配串本身
/,/                                     匹配区间内容,常用语匹配配置文件模块内容

常见处理操作示例

##### 输出行
sed -n 'p' txt                          输出所有行
sed -n '1p' txt                         输出第一行
sed -n '$p' txt                         输出最后一行
sed -n '4,+2p' txt                      输出第4行及其后2行
sed -n '{2p;4p;9p}' txt                 输出第2,4,9行
sed -n '/^root/p' txt                   输出以root开头的行
sed -n '/nologin$/p' txt                输出以nologin结尾的行
sed -n '/^root/p;/^m/p' txt             输出以root开头或以m开头的行
sed -n 'p;n' txt                        输出奇数行,'n;p'读入偶数行
sed -n '$=' txt                         输出行数,wc -l 输出行数加文件名
sed -n '/^device /,//p'                 sed -n '/区间开始标识/,/区间结束标识/p' oldboy.log
sed 's/swap/No/Ig'                      忽略大小写替换

##### 删除行
sed 'd' txt                             删除所有行
sed '/^$/d' txt                         删除所有空行
sed '/[0-9]/d' txt                      删除所有带数字的行
sed '/nologin$/!d' txt                  删除所有非nologin结尾的行
sed '/^#/\|/^$/d' txt                   删除所有注释行和空行,\|
sed '/bin/d;/root/d' txt                删除所有包含'bin','root'的行

##### 替换行
sed 's/xml/XML/' txt                    将每行中的第一个xml替换为XML
sed 's/xml/XML/3' txt                   将每行中的第三个xml替换为XML
sed '1s/xml/XML/3' txt                  将第一行中的第三个xml替换为XML
sed 's/xml//g' txt                      将每行中的xml都删除,替换为空
sed 's/doc/&s/g' txt                    将每行中的doc替换为docs,&表示查找串
sed '1,4s/^/#/' txt                     注释掉第1到4行
sed '1,4s/^#//' txt                     删除第1到4行的注释
sed 's/^#root/root/' txt                删除以root开头的行注释
sed 's/xml\|XML\|e//g' txt              删除所有的'xml','XML','e'的字符串
sed '/^HOSTNAME/cHOSTNAME:w' txt        将HOSTNAME整行替换为HOSTNAME:w, c为替换
sed '/^HOSTNAME/aHOSTNAME' txt          在HOSTNAME行下新增HOSTNAME, a为插入

##### 综合应用
删除文件中第2个,最后一个字符
sed 's/.//2;s/.$//' txt
将文件中每行第一个,第二个字符互换
sed -r 's/(.)(.)(.*)/\2\1\3/' txt
删除文件中所有的数据,空行
sed -r 's/[0-9]|^$//g' txt

awk

awk是一个强大的分析工具,简单来说awk逐行读入,默认以空格为分隔符将每行切片,切开的部分再进行分析处理

参数
-F                                      指定处理文本的分隔符
-v                                      设定变量。如-va=20,a可在指令中使用
-f                                      指定awk脚本处理文件,如awk -f a.awk passwd
运算符
=                                       赋值
?:                                      C条件表达式
||                                      逻辑或
&&                                      逻辑并
~                                       匹配正则表达式
<= == >= !=                             关系运算符
空格                                    连接
+ -                                     加减
* / %                                   乘,除,余
^ **                                    求幂
++ --                                   增加或减少
in                                      数组成员
内置变量
ARGC                                    命令行参数个数
ARGV                                    命令行参数排列
ENVIRON                                 支持队列中系统环境变量应用
FILENAME                                awk浏览的文件
getline                                 获取下一行
FS                                      设置分隔符,等价于命令行-F
NF                                      统计每行的总数
NR                                      所有输入文件的总行数
FNR                                     当前输入文件的总行数(经常与NR结合处理俩个文件)
OFS                                     输出时指定域分隔符,默认为空
ORS                                     输出时指定换行符,默认为换行
RS                                      指定输入时的换行符
$0                                      指整条记录
$1                                      表示当前行的第一个域,依次类推
$NF                                     表示最后一列的信息
$NR                                     表示第一行的第一列,第二行的第二列,第三行的第三列。以此类推
常用命令展示
awk '/root/' passwd                     搜索文本中所有带root的行
awk -F: '/root/ {print $7}' passwd      搜索文本中所有带root行的bash
awk 'NR==2 {print $0}' passwd           打印第二行信息
awk -F: '$3>90' passwd                  打印第三列大于90的行
awk -F: '{print $(NF-1)}' passwd        打印倒数第二列内容
awk 'NR>13 && NR<17 {print $0}'         打印第14~16列内容
awk -F[:/] '{print $1,$NF}' passwd      多分隔符使用,无优先顺序。显示用户名和最后的nologin
awk 'BEGIN{}{}END{}'                    先执行BEGIN{}里面的语句,再执行{},然后执行END{}
awk -F: '$1 ~ /^r/' {print $0}'         匹配第一列字符串以r开头的行
awk 'BEGIN{IGNORECASE=1} /this/'        忽略大小写
awk -F: 'BEGIN{OFS=":"}{print $3,$5}'   输出时指定显示的分隔符
awk -F: 'BEGIN{RS="\n\n"}{print $1}'    指定以两个换行符为行分隔符
awk 'length>=70' passwd                 打印长度大于70的行
awk '/^device /,//'                     取区间值,device{}这个模块的内容。/,/表示区间内容
awk计算
awk -F: '{sum+=$3}END{print sum}'       计算第三列的总和
awk -F: '{$3>= 900}END{print NR}'       统计uid大于900的人数

awk -F: 'BEGIN{a=0}{if ($3>a) a=$3}{print a}' passwd 
# 求列中最大值(赋值一个a,遇到一个比a大的值便赋值给a)

awk '{for (i=2;i<=NF;++i) sum+=$i}{print $0,sum}{sum=0}'
# 计算行数据,sum=0每执行完一次行数据后将sum归置为0

awk '{h[$1]+=$2}END{for(pol in h)printpol,h[pol]}' array_add.txt
# 统计$1相同后面的$2数字加在一起,按字母的顺序输出

awk -F[/" ":] '{a[$4":"$5"\t"$8]++}END{for (ip in a) print a[ip],ip}' a|sort -k2|column -t
# 统计每分钟每个IP的访问次数,$4,$5为时间,$8为IP
awk内置函数
system                                  执行特定的命令然后返回其退出状态。返回值为 0 表示命令执行成功;非 0 表示命令执行失败
# awk 'BEGIN { ret = system("date"); print "Return value = " ret }'
systime                                 得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数
# awk 'BEGIN{now=systime();print now}'
strftime(fotmat,timestamp)              格式化时间戳
# awk 'BEGIN {print strftime("Time = %m/%d/%Y %H:%M:%S", systime())}'
# %D等价于%m/%d%y %F等价于%Y-%m-%d %R等价于%H:%M %u表示星期 %j表示一年中的第几天
printf                                  格式化字符串输出,与print区别在于printf输出默认不会换行
                                        %d 十进制有符号整数
                                        %u 十进制无符号整数
                                        %f 浮点数
                                        %s 字符串   %-10s表示左对齐10个字符,$+20s表示右对齐
                                        %p 指针值
                                        %g 自动选择合适格式表示
                                        
gsub[old,new,[In]]                      gsub 是全局替换
sub                                     sub 函数执行一次子串替换。它将第一次出现的子串用 regex 替换。第三个参数是可选的,默认为 $0
length                                  字符串长度,默认为$0
# awk -F: 'length($7)<10' passwd
tolower                                 将字符串都转换为小写
awk条件及循环
if
# if语句格式
# if (条件表达式)
#     动作1
# else if(条件表达式)
#     动作2
# else
#     动作3

示例
# 以:分隔,只打印第三列范围在50~100的行信息
awk 'BEGIN{FS=":"}{if($3>50 && $3<100) print $0}' passwd

for
for (initialisation; condition; increment/decrement) 
    action
# for语句首先执行初始化动作( initialisation ),然后再检查条件( condition )。
如果条件为真,则执行动作( action ),然后执行递增( increment )或者递减( decrement )操作
只要条件为 true 循环就会一直执行。每次循环结束都会进条件检查,若条件为 false 则结束循环。
示例
awk 'BEGIN { for (i = 1; i <= 5; ++i) print i }'
输出结果为:
1
2
3
4
5
while
While
While 循环的语法如下:

while (condition)
    action
While 循环首先检查条件 condition 是否为 true ,若条件为 true 则执行动作 action。
此过程一直重复直到条件 condition 为 flase 才停止
awk 'BEGIN{i=1;while (i<5) {print i;i++}}'
输出结果为:
1
2
3
4
break
break 用以结束循环:
$ awk 'BEGIN {
   sum = 0; for (i = 0; i < 20; ++i) { 
      sum += i; if (sum > 50) break; else print "Sum =", sum 
   } 
}'
continue
Continue 语句用于在循环体内部结束本次循环,从而直接进入下一次循环迭代。
$ awk 'BEGIN {for (i = 1; i <= 20; ++i) {if (i % 2 == 0) print i ; else continue} }'
exit
Exit退出本循环

paste

paste主要用于合并俩个文件

主要参数
-s                                              把文件变为一行
-d                                              指定换行符