首页 > 系统相关 >Shell阶段10 awk工作原理, 内部变量, 正则/比较/条件/逻辑表达式, 判断语句, 循环语句, awk数组

Shell阶段10 awk工作原理, 内部变量, 正则/比较/条件/逻辑表达式, 判断语句, 循环语句, awk数组

时间:2024-06-02 22:43:22浏览次数:59  
标签:语句 10 passwd shell01 awk print root shell13

AWK

什么是awk
awk是一个编程语言
主要作用: 对文本和数据的处理

awk处理数据的流程
1.扫描文件内容,从上到下进行扫描,按照行进行处理
2.寻找匹配到的内容,进行读取到特定的模式中,进行行处理
3.行满足指定模式动作,则输出到屏幕上面,不满足丢弃
4.接着读取下一行继续处理,接着循环,直到文件的结尾

awk语法格式
awk [选项] command files

三种格式
行处理前        行处理中        行处理后
BEGIN            执行的命令       最后的显示 END

#行处理前
[root@shell01 ~]# awk 'BEGIN{print 1 + 1}'
2

#行处理前+行处理中  (-F是简写)
[root@shell01 ~]# awk -F: '{print $1}' /etc/passwd
root
bin
#-F为处理前,等于BEGIN{FS=':'}     {print $1}为行处理中
[root@shell01 ~]# awk 'BEGIN{FS=":"}{print $1}' /etc/passwd

#输出分隔符默认为空格,这里修改为#
[root@shell01 ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}' /etc/passwd
root#x
bin#x
daemon#x

#行处理前+行处理中+行处理后    (END为行处理后,会在最后执行)
[root@shell01 ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}END{print "内容打印结束"}' /etc/passwd
root#x
bin#x
...
内容打印结束

#行处理前+行处理中+行处理后 (文件有几行,就打印几行OK)
[root@shell01 ~]# awk 'BEGIN{print 1+1}{print "OK"}END{print "内容打印结束"}' /etc/hosts
2
OK
OK
内容打印结束

[root@shell01 ~]# cat test.txt 
10 10 10
[root@shell01 ~]# awk '{print $1+$2}' test.txt
20

[root@shell01 ~]# awk -F: '{print $1,$3}' /etc/passwd
root 0
bin 1


awk的工作原理
1.awk将文件中的每一行作为输入,将每一行的数据赋值给内部变量    $0
2.awk开始进行字段分解,根据指定的分隔符,将每个字段进行赋值给内部变量 $1 $2 $3
3.awk默认的分隔为空白字符,由内部变量FS来确定,也可以使用-F进行指定对应的分隔符
4.awk处理时使用print进行打印已分隔后的字段
5.awk打印输出结果之后,不同字段之间由空格进行分隔,这个空格是由不同字段之间的逗号进行映射的,由内部变量OFS进行修改,OFS默认的输出分隔符就是空格
6.awk输出一行内容后,重新读取下一行内容,会覆盖内部变量$0,然后新的字符进行字段分割并进行处理。

#awk的命令格式
    匹配    模式    动作

#匹配 模式(root就是模式)
[root@shell01 shell13]# awk '/root/' passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

#动作
[root@shell01 shell13]# awk '{print $1}' passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

#模式+动作
[root@shell01 shell13]# awk -F: '/root/{print $1}' passwd 
root
operator

#当根分区使用率大于多少则打印Available
[root@shell01 shell13]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda3       18863104 1875848  16987256  10% /
devtmpfs          487048       0    487048   0% /dev
[root@shell01 ~]# df |awk '/\/$/{print $4}'
16987256
[root@shell01 ~]# df |awk '/\/$/{ if ($3>180000)  print $4}'
16987256

Awk的内部变量

1. 输入分隔符
FS        输入分隔符    默认以空白字符为分隔符

[root@shell01 ~]# awk -F: '{print $1}' passwd
[root@shell01 ~]# awk 'BEGIN{FS=":"}{print $1}' passwd
#指定多个分隔符, :和空格
[root@shell01 ~]# awk -F '[ :]' '{print $3}' passwd

#获取ip地址
[root@shell01 shell13]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:49:ee:cc brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 brd 10.0.0.255 scope global noprefixroute eth0
#注意:行开头空格前面也算一个字符;如果碰到' /'空格和斜杠一起,算一个分割符
[root@shell01 ~]# ip a s eth0|awk -F '[ /]*' 'NR==3{print $3}' 

2. 输出分隔符
OFS        默认输出分隔为空格,    打印的时候用逗号作为分割,逗号就是输出分隔符,在显示的时候,默认映射为空格。

[root@shell01 shell13]# awk -F: '{print $1,$2}' passwd 
root x
bin x
[root@shell01 shell13]# awk -F: '{print $1$2}' passwd 
rootx
binx
#-v指定内部变量,分隔符为@
[root@shell01 shell13]# awk -F: -vOFS="@" '{print $1,$2}' passwd 
root@x
bin@x
[root@shell01 shell13]# awk -F: 'BEGIN{OFS="$"}{print $1,$2}' passwd 
root@x
bin@x

3. 内部变量NF    最后一列

# NF    表示每一行最后一列(列数)        $NF    打印最后一列的内容
[root@shell01 shell13]# awk -F: '{print $NF}' passwd 
/bin/bash
/sbin/nologin
/sbin/nologin
[root@shell01 shell13]# awk -F: '{print NF}' passwd 
7
7


4. 内部变量$0
$0 表示整行内容

#没有过滤,打印所有内容
[root@shell01 shell13]# awk '{print $0}' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#取第一行
[root@shell01 shell13]# awk 'NR==1{print $0}' passwd
root:x:0:0:root:/root:/bin/bas


5. 内部变量NR
NR    表示是行号    $NR不可用

#NR显示行号
[root@shell01 shell13]# awk '{print NR,$0}' passwd 
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

#第一行
[root@shell01 shell13]# awk 'NR==1' passwd 
root:x:0:0:root:/root:/bin/bash
[root@shell01 shell13]# awk 'NR==1{print $0}' passwd 
root:x:0:0:root:/root:/bin/bash

6. 内部变量    FNR
#FNR    显示行号,针对多个文件时进行处理
        不同的文件显示各自的行号
        
#下面两个文件行号叠加了,没有区分
[root@shell01 shell13]# awk '{print NR,$0}' passwd test.txt
1 root:x:0:0:root:/root:/bin/bas
...
10 2: eth0: <BROADCASE,MU...
#下面两个文件行号各区计算
[root@shell01 shell13]# awk '{print FNR,$0}' passwd test.txt
1 root:x:0:0:root:/root:/bin/bas
...
1 2: eth0: <BROADCASE,MU...


#了解
#7. RS 输入记录分隔符    ORS 输出记录分隔符

8. awk格式化输出

[root@shell01 ~]# date |awk '{print "今年是: "$NF"年","今月为: "$2"月"}'
今年是: 2024年 今月为: Jun月
[root@shell01 ~]# awk -F: '{print "用户为: "$1,"UID为:"$3,"GID为: "$4}' /etc/passwd
用户为: root UID为:0 GID为: 0
用户为: bin UID为:1 GID为: 1
用户为: daemon UID为:2 GID为: 2

printf 函数输出(了解)
%表示内容  -表示左对齐   20表示占20个字符   s表示字符类型
[root@shell01 ~]# awk -F: '{printf "%-20s %-10s %-10s\n", "用户为: "$1,"UID为:"$3,"GID为: "$4}' /etc/passwd
用户为: root            UID为:0     GID为: 0   
用户为: bin             UID为:1     GID为: 1   
用户为: daemon          UID为:2     GID为: 2 

Awk模式动作

1. 正则表达式

#获取root开头的
[root@shell01 ~]# awk '/^root/' /etc/passwd
#获取每一行等于root开头的,和上面效果相同,~表示等于
[root@shell01 ~]# awk '$0 ~/^root/' /etc/passwd
#获取第4列以root开头的
[root@shell01 ~]# awk -F: '$4 ~/^root/' /etc/passwd

#取反,不以root开头
[root@shell01 ~]# awk '!/^root/' /etc/passwd
[root@shell01 ~]# awk '$0 !~/^root/' /etc/passwd
#不取第4列以root开头的
[root@shell01 ~]# awk -F: '$4 !~/^root/' /etc/passwd

2. 比较表达式

关系运算符
<        小于
<=        小于等于
==        等于
>        大于
>=        大于等于
!=        不等于

[root@shell01 shell13]# awk -F: '$3==0' passwd
root:x:0:0:root:/root:/bin/bash
#下面{print $0}可以省略,默认打印该行
[root@shell01 shell13]# awk -F: '$5<0{print $0}' passwd

#字符串比较 (字符串最好用引号引起来)
[root@shell01 shell13]# awk -F: '$1=="root"' passwd 
root:x:0:0:root:/root:/bin/bash
#不等于
[root@shell01 shell13]# awk -F: '$4 != "root"' passwd 
 
[root@shell01 ~]# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/sda3       18863104 1875848  16987256  10% /
devtmpfs          487048       0    487048   0% /dev
[root@shell01 ~]# df |awk '/\/$/'|awk '$3 > 1800000{print $4}'
16987148

3. 条件表达式

#如果第3列大于2万就打印整行
[root@shell01 ~]# awk -F: '{if($3>20000)print $0}' /etc/passwd
#每一行第3列大于1000打印最后一列,否则打印第一列
[root@shell01 ~]# awk -F: '{if($3>1000){print $NF} else {print $1}}' /etc/passwd

4. 运算表达式

[root@shell01 ~]# awk -F: '$3 * 100 > 50000' /etc/passwd
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
#如果$3乘以10大于1000打印最后一列,否则打印第一列
[root@shell01 ~]# awk -F: '{if($3*10>1000){print $NF} else {print $1}}' /etc/passwd
root
bin

[root@shell01 shell13]# awk -F: '/sync/{print $3}' passwd
5
[root@shell01 shell13]# awk -F: '/sync/{print $3 + 10}' passwd
15
[root@shell01 shell13]# awk -F: '/sync/{print $3*2}' passwd
10
[root@shell01 shell13]# awk -F: '/sync/{print $3/5}' passwd
1
[root@shell01 shell13]# awk -F: '/sync/{print $3^5}' passwd
3125
[root@shell01 shell13]# awk -F: '/sync/{print $3%5}' passwd
0
[root@shell01 shell13]# awk -F: '/sync/{print $3,$4}' passwd
5 0
[root@shell01 shell13]# awk -F: '/sync/{print $3+$4}' passwd
5

5. 逻辑操作符
&&        并且
||        或者
!        非

#行数大于2并且行数小于4
[root@shell01 shell13]# awk 'NR>2 && NR<4' passwd 
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@shell01 shell13]# awk 'NR>2 || NR<4' passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#不为1的行
[root@shell01 shell13]# awk 'NR!=1' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#第1列为root且第三列大于10
[root@shell01 shell13]# awk -F: '$1 ~/root/ && $3 > 10' passwd
#不以root开头
[root@shell01 shell13]# awk '!/^root/' passwd

Awk判断语句

if

#1.打印系统管理员用户的数量
[root@shell01 ~]# awk -F: '$3==0' /etc/passwd |wc -l
#通过判断第三列是否为零,i进行累计,最后输出i
[root@shell01 ~]# awk -F: '{if($3==0){i++}}END{print "当前系统管理员用户的数量:"i}' /etc/passwd
当前系统管理员用户的数量:1

if    else

#打印系统管理员的数量和其他用户的数量
[root@shell01 ~]# awk -F: '{if($3==0){i++}else{j++}}END{print "当前系统管理员用户数量:"i,"当前系统其他用户数量:"j}' /etc/passwd
当前系统管理员用户数量:1 当前系统其他用户数量:23
#这里END中写两条print命令,用;隔开
[root@shell01 ~]# awk -F: '{if($3==0){i++}else{j++}}END{print "当前系统管理员用户数量:"i;print "当前系统其他用户数量:"j}' /etc/passwd
当前系统管理员用户数量:1
当前系统其他用户数量:23

if    else    if    else

#打印系统管理员的数量和系统用户的数量及普通用户的数量 (小于1000系统用户,大于1000普通用户)
[root@shell01 ~]# awk -F: '{if($3==0){a++}else{if($3>0 && $3<1000){b++}else{c++}}}END{print "管理员数量:"a,"系统用户数量:"b,"普通用户数量:"c}' /etc/passwd
管理员数量:1 系统用户数量:22 普通用户数量:1

Awk循环语句

while循环
[root@shell01 shell13]# awk 'BEGIN{ i=1; while(i<=3){print i; i++}}'
1
2
3

#相当于每一行,都要循环到总列数,并打印1-列数
[root@shell01 ~]# awk -F: '{i=1; while(i<=NF){print i;i++}}' /etc/passwd

#每一行都打印10次
[root@shell01 ~]# awk -F: '{i=1; while(i<=10){print $0;i++}}' /etc/passwd

for循环
#把每行所有内容一个个打印出来
[root@shell01 shell13]# awk -F: '{for(i=1;i<=NF;i++){print $i}}' passwd

awk数组

将需要统计的某个字段作为数组的索引,然后对索引进行遍历

#统计数组 (把最后一列作为索引)
[root@shell01 ~]# awk -F: '{shell[$NF]++}' /etc/passwd
#计算次数
[root@shell01 ~]# awk -F: '{shell[$NF]++}END{for(i in shell)print i"出现了"shell[i]"次"}' /etc/passwd
/bin/sync出现了1次
/bin/bash出现了1次
/sbin/nologin出现了20次
/sbin/halt出现了1次
/sbin/shutdown出现了1次

#站访问状态统计
[root@shell01 shell13]# ss -an
Netid State      Recv-Q Send-Q     Local Address:Port                    Peer Address:Port           
nl    UNCONN     0      0                      0:0                                   *
nl    UNCONN     0      0                      0:5717                                *
nl    UNCONN     0      0                      0:5717                                *
nl    UNCONN     4352   0                      4:7971                                *
[root@shell01 ~]# ss -an|awk '{status[$2]++}END{for(i in status)print i,status[i]}'
LISTEN 38
ESTAB 90
State 1
UNCONN 63

 

标签:语句,10,passwd,shell01,awk,print,root,shell13
From: https://www.cnblogs.com/ludingchao/p/18227774

相关文章

  • Windows10系统中安装与配置PyTorch(无GPU版本)
    文章目录1.什么是PyTorch2.PyTorch的安装与配置(无GPU)2.1创建环境2.2安装pytorch库(无GPU)2.3验证安装结果1.什么是PyTorchPyTorch是一种用于构建深度学习模型且功能完备的开源框架,通常用于处理图像识别和语言处理等应用当中的机器学习。PyTorch保留了Torch(L......
  • 【Python基础】循环语句(5073字)
    文章目录@[toc]什么是循环Python中的循环方式while循环格式示例运行过程应用while循环嵌套示例1示例2for循环格式示例内置函数range()的用法range(x)range(x,y)range(x,y,z)应用break与continuebreakwhile循环中的break未使用break使用breakfor循环中的breakc......
  • F1000 Research 准备研究文章
    准备研究文章  LINK  本页提供有关为F1000Research撰写研究文章的信息,包括文章中必须包含的关键部分。另请参阅F1000Research的编辑政策。此处提供了研究文章的模板。标准研究文章应呈现发现和见解的独创性,并为各自的研究领域提供理论、实证、实验和/或方法论的进步。还......
  • 100311. 无需开会的工作日
    题目描述给你一个正整数days,表示员工可工作的总天数(从第1天开始)。另给你一个二维数组meetings,长度为n,其中meetings[i]=[start_i,end_i]表示第i次会议的开始和结束天数(包含首尾)。返回员工可工作且没有安排会议的天数。注意:会议时间可能会有重叠。情况描述6月2日周......
  • # window10 设置一个【自定义运行】命令行快捷方式
    window10设置一个【自定义运行】命令行快捷方式window10[运行】命令行打不开,可采用如下简单快捷方法:1、右键点击桌面空白处,然后点击【新建】,再点击【快捷方式】。2、在【请键入对象的位置】文本框输入:explorershell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}3......
  • # WIN10/WIN11 找不到【应用商店 Microsoft.WindowsStore】怎么办?
    WIN10/WIN11找不到【应用商店Microsoft.WindowsStore】怎么办?解决方法:1、右键【开始】菜单,点击【WindowsPowerShell(管理员)】,输入:Get-AppxPackage-allusers|SelectName,PackageFullName2、查询到的目录中找到【Microsoft.WindowsStore】,复制后面的可安装版本......
  • 解读10个高考填志愿你必须知道的名词(附:高考志愿填报指导音频)
    大家好,今天我们就来和大家解读一下十个填志愿你必须知道的名词。第一个名词:录取批次录取批次是指根据不同高校情况所划分的录取顺序录取步骤。分为本科一批次,本科二批次,专科提前批次,高职批次,需要注意的是,录取批次具有严格的顺序性。上一批次未录取完毕,不得进行下一批次的录......
  • TCP_FLAGS_INVALID_10: [finwait-2] (otw SEQ)-> ACK(seq) [finwait-2]
    测试目的:验证TCP在FINWAIT-2状态下,接收到一个序列号超出窗口(OTW)的段时,是否能够发送一个ACK段,并保持在相同的状态。描述:TCP在FINWAIT-2状态下,如果接收到一个没有RST标志且序列号超出接收窗口的段,它必须发送一个ACK段,其中确认号表示期望的下一个序列号,并保持在FINWAIT-2状......
  • Linux-shell的108个案例
    通用函数库#catdiy_func.shredecho(){ #颜色开头部分 echo-ne"\e[5;31m" #取出要加上颜色的内容 echo-n"$@" #颜色的结束部分 echo-e"\e[0m" #echo-e"\e[5;31m$@\e[0m"}greenecho(){ echo-ne"\e[1;32m" ec......
  • 英伟达赢麻了!马斯克xAI超级算力工厂曝光,10万块H100、数十亿美元
        ChatGPT狂飙160天,世界已经不是之前的样子。新建了免费的人工智能中文站https://ai.weoknow.com新建了收费的人工智能中文站https://ai.hzytsoft.cn/更多资源欢迎关注英伟达:尽管建,用的还是我的芯片,最近几年,随着大语言模型的飞速发展与迭代,科技巨头们都竞相投入......