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 指定换行符