文本三剑客之grep、sed、awk

回顾计划任务内容
小tips:当执行 cd /tmp || mkdir test1时,只有当前面执行cd/tmp执行失败后,后面执行的mkdir test1才会执行。

一次调度执行at

  • 语法格式
at <TIMESPEC>
now +5min
teatime tomorrow (teatime is 16:00)
noon +4 days
5pm august 3 2021
  • 例子
[root@localhost ~]# systemctl start atd
[root@localhost ~]# systemctl enable atd
[root@server1 ~]# at now +2min
at> useradd zhangsan
at> <EOT>
job 1 at Tue Feb 2 11:29:00 2021
[root@server1 ~]# atq
1 Tue Feb 2 11:29:00 2021 a root
[root@server1 ~]# id zhangsan
id: zhangsan: no such user
[root@server1 ~]# id zhangsan
uid=1000(zhangsan) gid=1000(zhangsan)=1000(zhangsan)

循环调度执行cron用户级

  • cron在使用之前必须要启动守护进程
[root@localhost ~]# systemctl start crond
[root@localhost ~]# systemctl enable crond
[root@localhost ~]# ps aux|grep crond
root 6242 0.3 0.0 126380 1656 ? Ss 16:27 0:00
/usr/sbin/crond -n
  • crond进程每分钟会处理一次计划任务
  • 存储位置
[root@localhost ~]# ls /var/spool/cron
  • 管理命令
[root@localhost ~]# crontab -l # 列出当前用户所有计划任务
[root@localhost ~]# crontab -r # 删除当前用户计划任务
[root@localhost ~]# crontab -e # 编辑当前用户计划任务
管理员可以使用 -u username,去管理其他用户的计划任务
[root@localhost ~]# vi /etc/cron.deny # 这个文件中加入的用户名无法使用cron
  • cron语法格式
分 时 日 月 星期 命令
* 表示任何数字都符合
0 2 * * * /run.sh # 每天的20 2 14 * * /run.sh # 每月1420 2 14 2 * /run.sh # 每年21420 2 * * 5 /run.sh # 每个星期520 2 * 6 5 /run.sh # 每年6月份的星期520 2 2 * 5 /run.sh # 每月2号或者星期52点 星期和日同时存在,那么就是或的关系
0 2 2 6 5 /run.sh # 每年62号或者星期52*/5 * * * * /run.sh # 每隔5分钟执行一次
0 2 1,4,6 * * /run.sh # 每月1号,4号,6号的20 2 5-9 * * /run.sh # 每月5-9号的2* * * * * /run.sh # 每分钟
0 * * * * /run.sh # 每整点
* * 2 * * /run.sh # 每月2号的每分钟

循环调度执行cron系统级

临时文件的清理 /tmp /var/tmp
系统信息的采集 sar
日志的轮转(切割) lgrotate
通常不是由用户定义
文件的位置

[root@localhost ~]# vim /etc/crontab # 默认没有定义任何计划任务
[root@localhost ~]# ls /etc/cron.d # 定义的计划任务每个小时会执行
0hourly sysstat
[root@localhost ~]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly # 每小时01分以root身份执
行/etc/cron.hourly/目录下的所有脚本
  • cron仅仅会执行每小时定义的脚本
[root@localhost ~]# ls /etc/cron.hourly/
[root@localhost ~]# cat /etc/cron.hourly/0anacron
/usr/sbin/anacron -s # anacron是用来检查是否有错过的计划任务需要被执行
[root@localhost ~]# vi /etc/anacrontab
1 5 cron.daily nice run-parts /etc/cron.daily
#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那
就执行
7 25 cron.weekly nice run-parts /etc/cron.weekly
#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被
执行,就会执行
©monthly 45 cron.monthly nice run-parts /etc/cron.monthly
#每隔一个月开机后 45 分钟检查 /etc/cron.monthly 目录内的文件是否被执行,如果一个月内没
有被执行,那就执行

通配符

通配符是shell在做PathnameExpansion时用到的。说白了一般只用于文件名匹配,它是由shell解析的,比如 find,ls,cp,mv等 shell常见通配符

*:匹配0或多个字符
?:匹配任意一个字符
[list]:匹配list中任意单个字符
[c1‐c2]:匹配c1‐c2中任意单个字符
[^c1‐c2]/[!c1‐c2]:不匹配c1‐c2中任意字符
{string1,string2,…}:匹配{}中任意单个字符串

  • shell 元字符
IFS:<tab>/<space>/<enter>
CR:<enter>
=:设定变量
$:取变量值
>/< :重定向
|:管道
&:后台执行命令
():在子shell中执行命令/运算或命令替换
{}:函数中执行/变量替换的界定范围
;:命令结束后,忽略其返回值,继续执行下一个命令
&&:命令结束后,若为true,继续执行下一个命令
||:命令结束后,若为false,继续执行下一个命令
!:非
#:注释
\:转义符
  • shell转义符
'':硬转义,内部所有shell元字符,通配符都会被关掉
"":软转义,内部

Linux三剑客之grep

grep作用:过滤文本内容
在这里插入图片描述
样本内容

[root@localhost ~]# cat test
asdkahsduoa
aslkdsl
oiofr
sdjo
A
F
aSDD
CASDC
asdo
ca

实例
实例1

练习题:
假设已经准备好了regular_express.txt

  1. 过滤下载文件中包含the关键字
    grep the regular_express.txt
  2. 过滤下载文件中不包含the关键字
  3. 过滤下载文件中不论大小写the关键字
    grep -i the 文件名
  4. 过滤test或taste这两个单词(管道要用扩展正则)
    egrep “test|taste” 文件名
  5. 过滤有oo的字节
    grep oo 文件名
  6. 过滤不想要oo前面有g的
    egrep -v “goo” 文件名
  7. 过滤oo前面不想有小写字母的
    egrep “[ ^a-z]oo” 文件名
  8. 过滤有数字的那一行
    egrep “[0-9]” 文件名
  9. 过滤以the开头的
    egrep " ^the" 文件名
    10.过滤g后面接2到5个o,然后在接一个g的字串
    egrep “go{2,5}g” 文件名
    11.过滤g后面接2个以上o的
    egrep “go{2,}” 文件名

Linux三剑客之sed

文本编辑工具,也可以支持查询或者过滤
Linux sed命令是利用script来处理文本文件。
sed可依照script的指令,来处理、编辑文本文件。
sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

语法:

sed的命令格式: sed [option] 'sed command' filename
sed的脚本格式:sed [option] ‐f 'sed script' filename
常用选项:
‐n :只打印模式匹配的行
‐e :直接在命令行模式上进行sed动作编辑,此为默认选项
‐f :将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作
‐r :支持扩展表达式
‐i :直接修改文件内容
查询文本的方式
使用行号和行号范围
x:行号
x,y:从x行到y行
x,y!:x行到y行之外
/pattern:查询包含模式的行
/pattern/, /pattern/:查询包含两个模式的行
/pattern/,x:x行内查询包含模式的行
x,/pattern/:x行后查询匹配模式的行

动作说明

常用选项:
p:打印匹配的行(‐n)
=:显示文件行号
a\:指定行号后添加新文本
i\:指定行号前添加新文本
d:删除定位行
c\:用新文本替换定位文本
w filename:写文本到一个文件
r filename:从另一个文件读文本
s///:替换
替换标记:
g:行内全局替换
p:显示替换成功的行
w:将替换成功的结果保存至指定文件
q:第一个模式匹配后立即退出
{}:在定位行执行的命令组,用逗号分隔
g:将模式2粘贴到/pattern n/

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何东西;
i :插入, i的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g,1到20行老的全都替换成新的 g代表行内全局替换

实例

在testfile文件的第四行后添加一行,并将结果输出到标准输出

[root@localhost ~]# sed -e 4a\newline test
line one
line two
line three
line four
newline
line five

此时这里的内容只是在内存里修改了并没有文件生效,如果想要文件真的生效需要加-i

以行为单位的新增/删除
将 /etc/passwd 的内容列出并且列印行号,同时,请将第 2~5 行删除

nl命令可以列出行号

nl /etc/passwd | sed '2,5d'

sed 的动作为 ‘2,5d’ ,那个 d 就是删除!因为 2-5 行给他删除了,所以显示的数据就没有 2-5 行罗~ 另外,注意一下,原本应该是要下达 sed -e 才对,没有 -e 也行啦!同时也要注意的是, sed 后面接的动作,请务必以 ‘’ 两个单引号括住喔!

只要删除第 2 行

nl /etc/passwd | sed '2d'

要删除第 3 到最后一行

这里的$代表最后一个字符(正则操作)
nl /etc/passwd | sed '3,$d'

在第二行后(亦即是加在第三行)加上『hello world』字样

nl /etc/passwd |sed '2a\hello world'

加在第二行前面 -i 插入

nl /etc/passwd |sed '2i\hello world'

增加多行文字

nl /etc/passwd | sed '2i\hello world\
nihao\		(如果这里写\n会被识别成转义字符)
\zaijian\
'

以行为单位的替换与显示

将第2-5行的内容取代成为『No 2-5 number』 c 取代

nl /etc/passwd | sed '2,5c\No 2-5number'

仅列出 /etc/passwd 文件内的第 5-7 行
p打印,p动作要放在后面 、-n 只打印模式匹配的行

nl /etc/passwd | sed '5,7p'这里5到7p会打印出全部内容
只有加-n 才是打印所有匹配出来的内容
nl /etc/passwd | sed -n '5,7p'

数据的搜寻并显示
搜索 /etc/passwd有root关键字的行

nl /etc/passwd |sed -n '/root/p'

删除/etc/passwd所有包含root的行,其他行输出

nl /etc/passwd | sed '/root/d'

数据的搜寻并执行命令
搜索/etc/passwd,找到root对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把bash替换为blueshell,再输出这行.
s 取代

nl /etc/passwd | sed -n '/root/{s/bash/blueshell/p;q}'

最后的q是退出,不然会继续找下去

数据的搜寻并替换
除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并取代。

g表示这一行如果出现重复的都会替换掉,但如果不加g只会找到第一个需要替换的。只会控制一行内出现多次。
g行内全局替换

sed 's/要被取代的字串/新的字串/g'

取有IP地址那一行

ifconfig | sed -n "/netmask/p" 

删除IP地址前面和后面的东西

ifconfig | sed -n "/netmask/p"|head -n1|sed 's/^.*inet //'|sed 's/netmask.*$//'

^.是把inet前面的空格全部替换没了 //中间没有加东西表示替换为空
netmask.
$表示从metmask到结尾全部选中
或者

ip a|sed -n '/inet /p'|sed 's/^.*inet //g'|sed
's/\/.*$//g'|sed -n '2p'

多点编辑
一条sed命令,删除/etc/passwd第三行到末尾的数据,并把bash替换为blueshell

nl /etc/passwd | sed '3,$d'|sed 's/bash/blueshell/g'

或者

nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'

**直接修改文件内容(危险动作)**加i可以最后再加,加之前先做其他动作,当得到预期和结果一样时,加i

练习题:

  • 显示test.txt文件的3-9行;
    sed -n “3-9p” text.txt
  • 在文件第一行添加haha,文件结尾一行替换为yesyes
    cat test | sed ‘1a\haha’ | sed ‘$c\yesyes’
  • 用haha替换oo,打印前20行
    cat test | sed ‘s/haha/oo/g’ | sed -n ‘1,20p’
  • 删除空行和以#开头的行
    cat test | sed “/^ #/d” | sed “/^$/d”
  • 在第八行下面插入hahaha第十行上面插入lalala;
    sed "8a\hahaha’ | sed "10i\lalala’ test
  • 删除20到30行的最后一个字符
    sed ‘20,30s/.$ //’ test
  • 为文件中每个大写字母添加括号,因为是分组属于扩展正则所以要加 -r \1表示对自己的调用
    第一个括号是分组,第二个括号是对\1自己调用加括号
    sed -r ‘s/([A-Z])/( \1)’
  • 文件中出现所有sbin都被替换为hahaha
    nl /etc/passwd | sed ‘s/sbin/hahaha/g’
  • 解除文件注释,并删除4-6行
    sed ‘s/^#//’ | sed ‘4-6d’ /etc/passwd
  • 删除1-3行并用root替换sbin
    nl /etc/passwd | sed ‘s/sbin/root/g’ | sed ‘1,3d’
  • 删除1-8行并打印1-20行;
    nl /etc/passwd | sed ‘1,8d’ | sed -n ‘1,20p’
  • 删除所有包含mail的行
    nl /etc/passwd | sed ‘/mail/d’
  • 把20行以后所有行的末尾加上awr,&符合不表示替换而是把后面的awr添加进去
    nl /etc/passwd | sed ‘20, s / . s/. s/./&awr’
  • 打印1到20行,删除25行之后所有的行
    nl /etc/passwd | sed -n ‘1,20p’ | sed ‘25,$d’
  • 将字符串/mail替换成/hahaha,打印20-40行;
    nl /etc/passwd | sed ‘s/mail/hahaha/g’ | sed -n ‘20,40p’

Linux三剑客之awk

awk为文本分析工具
使用方法

awk '{pattern + action}' {filenames}

其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本

awk 的原理

[root@localhost ~]# awk -F: '{print $0}' /etc/passwd

-F 表示指定分隔符,方便后面进行切割
‘{print $0}’ 表示指定的动作
NR:指定有多少行
NF:指定有多少列
执行 awk 时,它依次对/etc/passwd 中的每一行执行 print 命令。
在这里插入图片描述

[root@localhost ~]# awk -F":" '{print $1}' /etc/passwd
[root@localhost ~]# awk -F":" '{print $1 $3}' /etc/passwd
[root@localhost ~]# awk -F":" '{print $1" " $3}' /etc/passwd
[root@localhost ~]# awk -F":" '{print "username:"$1"\t\tuid:" $3}'
/etc/passwd

-F参数:指定分隔符,可指定一个或多个
print 后面做字符串的拼接

实例:

示例一:只查看test.txt文件(100行)内第20到第30行的内容(企业面试)

cat test.txt | sed -n '20,30p'

或者

seq 100相当于取一个数字循环,默认从1100
seq 100 >test.txt
awk '{if(NR>=20 && NR<=30)} print$0' test.txt

或者

tail默认查看文件末尾 -n20 查看末尾20行
tail test -n +20  表示从20行开始到末尾
tail test -n +20 | head -n 10取前10

实例二:已知test.txt文件内容为

[root@localhost ~]# cat test.txt
I am aaron, my qq is 1234567

请从该文件中过滤出’aaron’字符串与1234567,最后输出的结果为:aaron 1234567

-F指定分隔符 以列表的形式确定分隔符为空格和逗号 打印第三个和第八个字符 NF表示列数,可以取最后一列
awk -F '[ ,]' '(print $3,$8)' test
awk -f '[ ,]' '(print $3,$NF)' test
先是以逗号作为分隔符,在前面分割出来的前提下 awk 默认以空格为分隔符 找到第三列和最后一列
awk -F ',' '{print $1""$2}' test.txt | awk '{print $3""$NF}'

BEGIN 和 END 模块

BEGIN只执行一次并且执行在主体代码块{ 即’(print $3,$8)’ }之前。
END只执行一次并且执行在主体代码块之后。
BEGIN可以抛开文件单独执行,结果类似于echo而END不可以
BEGIN中没有文件的读取变量(即$1$2 等等)而END中是有的。但END中的$0是awk处理到最后的文本样式。

实例

实例一:统计/etc/passwd的账户人数

/etc/passwd本身一行就是一个账户 nl
cat /etc/passwd | wc -l
awk 'BEGIN {count=0;print "[start] user count is "count}{count++;print $0} END {print"[end]user count is"count}' /etc/passwd
后面/etc/passwd代表指定文件的路径,记得加封号;

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0

实例二:统计某个文件夹下的文件占用的字节数

ll | awk 'BEGIN {size=0}{size=size+$5}END{print "size is",size}'

在这里插入图片描述

[root@localhost ~]# ll | awk 'BEGIN {size=0} {size=size+$5} END{print "size
is ",size/1024/1024,"M"}'
size is 0.00139999 M
换算成有多少M

也可以直接用awk来写脚本语言如helloworld

awk 'BEGIN{print "hello world"}'

awk运算符

在这里插入图片描述在这里插入图片描述awk 赋值运算符:a+=5;等价于: a=a+5;其他同类

awk 'BEGIN {a=5;a+=5;print a}'

awk逻辑运算符:判断表达式 a>2&&b>1为真还是为假,后面的表达式同理

awk 'BEGIN{a=1;b=2;print(a>2&&b>1,a=1||b>1)}'

awk正则运算符:

这里的~是匹配正则表达式的意思
awk 'BEGIN{a="100testadd"; if(a~/100/){print "OK"}else{print "No"}}'

关系运算符:
如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比
较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。

[root@node-1 ~]# awk 'BEGIN{a="11";if(a>=9){print"OK"}}'
[root@node-1 ~]# awk 'BEGIN{a=11;if(a>=9){print"OK"}}'
OK
[root@node-1 ~]# awk 'BEGIN{a;if(a>=b){print"OK"}}'
OK

awk 算术运算符:
说明,所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0

[root@node-1 ~]# awk 'BEGIN{a="b";print a++,++a}'
0 2
[root@node-1 ~]# awk 'BEGIN{a="20b4";print a++,++a}'
20 22

三目运算符 ?:

[root@node-1 ~]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
ok
[root@node-1 ~]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
err

常用 awk 内置变量

在这里插入图片描述BEGIN里面用不到

FS=“\t” 一个或多个 Tab 分隔

[root@node-1 ~]# cat tab.txt
aa bb cc
这里的+是正则表达式表示可以出现一次或任意多次,"\t+"指定字符串这里要写双引号不能写单引号
[root@node-1 ~]# awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' tab.txt
aa bb cc

FS=“[[:space:]+]” 一个或多个空白空格,默认的,匹配到不符合的就停止。

[root@node-1 ~]# awk -F [[:space:]+] '{print $1,$2,$3,$4,$5}' tab.txt
aa bb cc
[root@node-1 ~]# awk -F [[:space:]+] '{print $1,$2}' tab.txt
aa bb

FS=“[” “:]+” 以一个或多个空格或:分隔

[root@node-1 ~]# awk -F [" ":]+ '{print $1,$2,$3}' hello.txt
root x 0

字段数量 NF :显示满足用:分割,并且有8个字段的

[root@node-1 ~]# awk -F ":" 'NF==8{print $0}' hello.txt
bin:x:1:1:bin:/bin:/sbin/nologin:888

记录数量 NR

[root@node-1 ~]# ifconfig br0 | awk -F [" ":]+ 'NR==2{print $3}'
192.168.0.241

RS 记录分隔符变量
将 FS 设置成"\n"告诉 awk 每个字段都占据一行。通过将 RS 设置成"",还会告诉 awk每个地址记录都由空白行分隔。

[root@node-1 ~]# cat awk.txt
#!/bin/awk
BEGIN {
FS="\n"
RS=""
}
{
print $1","$2","$3
}
[root@node-1 ~]# awk -f awk.txt recode.txt

在""分割符之内,符合\n分割的会被打印出来
OFS 输出字段分隔符

[root@node-1 ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' hello.txt
root#x#0
bin#x#1

ORS 输出记录分隔符

[root@node-1 ~]# cat awk.txt
#!/bin/awk
BEGIN {
FS="\n"
RS=""
ORS="\n\n"
}
{
print $1","$2","$3
}
[root@node-1 ~]# awk -f awk.txt recode.txt
Jimmy the Weasel,100 Pleasant Drive,San Francisco,CA 123456
Big Tony,200 Incognito Ave.,Suburbia,WA 64890

awk正则

在这里插入图片描述在这里插入图片描述正则应用
规则表达式
awk '/REG/{action} ’ file ,/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action进行处理

[root@node-1 ~]# awk '/root/{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@node-1 ~]# awk -F ":" '$5~/root/{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@node-1 ~]# ifconfig br0 | awk 'BEGIN{FS="[[:space:]:]+"}
NR==2{print$3}'
192.168.0.241

布尔表达式
awk ‘布尔表达式{action}’ file 仅当对前面的布尔表达式求值为真时, awk 才执行代码块。

[root@node-1 ~]# awk -F: '$1=="root"{print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@node-1 ~]# awk -F: '($1=="root")&&($5=="root"){print$0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

awk 的 if、循环和数组

条件语句
awk 提供了非常好的类似于 C 语言的 if 语句。

{
if ($1=="foo"){
if ($2=="foo"){
print"uno"
}else{
print"one"
}
}elseif($1=="bar"){
print "two"
}else{
print"three"
}
}

使用 if 语句还可以将代码:

! /matchme/ { print $1 $3 $4 }

转换成:

{
if ( $0 !~ /matchme/ ) {
print $1 $3 $4
}
}

while

循环结构
我们已经看到了 awk 的 while 循环结构,它等同于相应的 C 语言 while 循环。 awk 还有"do…while"循环,它在代码块结尾处对条件求值,而不像标准 while 循环那样在开始处求值。
它类似于其它语言中的"repeat…until"循环。以下是一个示例:
do…while 示例

{
count=1do {
print "I get printed at least once no matter what"
} while ( count !=1 )
}

与一般的 while 循环不同,由于在代码块之后对条件求值, "do…while"循环永远都至少执行一次。换句话说,当第一次遇到普通 while 循环时,如果条件为假,将永远不执行该循环。

for 循环
awk 允许创建 for 循环,它就象 while 循环,也等同于 C 语言的 for 循环:

for ( initial assignment; comparison; increment ) {
code block
}

以下是一个简短示例:

for ( x=1;x<=4;x++ ) {
print "iteration", x
}

break 和 continue
此外,如同 C 语言一样, awk 提供了 break 和 continue 语句。使用这些语句可以更好地控制 awk 的循环结构。

#!/bin/awk
BEGIN{
x=1
while(1) {
print "iteration",x
if ( x==10 ){
break
}
x++
}
}

continue 语句补充了 break

x=1
while (1) {
if ( x==4 ) {
x++
continue
}
print "iteration", x
if ( x>20 ) {
break
}
x++
}

continue在for中使用

#!/bin/awk
BEGIN{
for (x=1;x<=21;x++){
if (x==4){
continue
}
print "iteration",x
}
}

数组

AWK 中的数组都是关联数组,数字索引也会转变为字符串索引。
在awk中,数组叫关联数组,与我们在其它编程语言中的数组有很大的区别。关联数组,简单来说,类似于python语言中的dict、java语言中的map,其下标不再局限于数值型,而可以是字符串,即下标为key,value=array[key]。竟然为key,那其下标也不再是有序的啦。

#!/bin/awk
BEGIN{
cities[1]="beijing"
cities[2]="shanghai"
cities["three"]="guangzhou"
for( c in cities) {
print cities[c]
}
# 这里的打印是无序的,因为是字符串
print cities[1]
print cities["1"]
print cities["three"]
}

用 awk 中查看服务器连接状态并汇总

netstat 基本与 ss 命令相同
^tcp 匹配tcp连接,以tcp开头
[root@node-1 ~]# netstat -an|awk '/^tcp/{++s[$NF]}END{for(a in s)print
a,s[a]}'
LISTEN 8
ESTABLISHED 1

常用字符串函数
在这里插入图片描述
在这里插入图片描述
字符串函数的应用
在 info 中查找满足正则表达式, /[0-9]+/ 用”!”替换,并且替换后的值,赋值给 info

[root@node-1 ~]# awk 'BEGIN{info="this is a test2010test!";gsub(/[0-
9]+/,"!",info);print info}'
this is a test!test!

如果查找到数字则匹配成功返回 ok,否则失败,返回未找到

[root@node-1 ~]# awk 'BEGIN{info="this is a test2010test!";print
index(info,"test")?"ok":"no found";}'
ok

从第 4 个 字符开始,截取 10 个长度字符串

[root@node-1 ~]# awk 'BEGIN{info="this is a test2010test!";print
substr(info,4,10);}'
s is a tes

分割 info,动态创建数组 tA,awk for …in 循环,是一个无序的循环。 并不是从数组下标1…n 开始

[root@node-1 ~]# awk 'BEGIN{info="this is a test";split(info,tA," ");print
length(tA);for(k in tA){print k,tA[k];}}'
4
4 test
1 this
2 is
3 a

练习题:

  1. 输出/etc/passwd 文件中以nologin结尾的行
	awk '/nologin$/{print $0}' /etc/passwd
  1. 判断服务器上所有用户类型(超级管理员、系统用户、普通用户)
    uid在第三个字段
    uid表示用户类型,0是超级管理员,1-999是系统用户,1000以上是普通用户
    这里的$1代表用户名
    思路:把uid切出来,然后if判断范围
awk -F :'{if ($3==0)print "超级管理员:" $1}{if($3<1000 && $3>0)print "系统用户:" $1}{if ($3>=1000)print"普通用户:"$1}' /etc/passwd
  1. 统计apache访问日志流量ip去重后取前10名
    uniq 去重
yum install httpd -y
awk '{print $1}' access_log | uniq |sort -u 
 
  1. 统计出每一行对应的总数,统计所有数字加起来
    这里的文件是test
awk 'BEGIN{count=0}{count+=$1+$2+$3}END{print"sum:" count}' test

或者
awk '{print($1+$2+$3)}' test

5.显示出包含LEE和包含kevin的行
文本可以自己搞一个,这里只提供思路,文件名为1.txt

awk '{if ($0 ~/Lee|kevin/)print $0}' 1.txt
或者
awk '/Lee|kebin/{print $0}' 1.txt

6.统计/etc/fstab文件中每个文件系统类型出现次数
/etc/fstab :这个文件是挂载用的,如果需要挂载就把默认信息写进去

/^#|^$/:一个正则表达式,以#开头或者空行的,!不匹配
[fs$3]++对数组递增 这里的$3表示文件系统名字,文件系统名字处在第三位。
awk '!/^#|^$/' {[fs$3]++} END {for (i in fs){print "文件系统:"i "出现次数:"fs[i]} /etc/fstab

7.计算男女生的总成绩,平均成绩
字段1:名字 字段2:分数 字段3:性别

awk 'BEGIN {mscore=0;fscore=0;mtotal=0;ftotal=0}{if($3=="male"){mscore+=$2;motal++}else{fscore+=$2;fotal++}}END{print "女生总分:" mscore,"女生平均:"mscore/mtotal,"男生总分:"fscore,"男生平均:"fscore/ftotal} '1.txt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值