千家信息网

文本三剑客之awk

发表于:2024-11-29 作者:千家信息网编辑
千家信息网最后更新 2024年11月29日,awk报告生成器,格式化文本输出 常用选项awk -F :"分隔符" 指明输入时用到的字段分隔符-v : 变量赋值基本用法基本格式:awk [options] 'program' file…Progr
千家信息网最后更新 2024年11月29日文本三剑客之awk

awk

报告生成器,格式化文本输出 

常用选项

awk -F :"分隔符" 指明输入时用到的字段分隔符
-v : 变量赋值

基本用法

基本格式:awk [options] 'program' file…
Program:pattern{action statements;..}

pattern和action

  pattern部分决定动作语句何时触发及触发事件
    BEGIN,END
  action statements对数据进行处理,放在{}内指明
    print, printf

分割符、域和记录

awk执行时,由分隔符分隔的字段(域)标记$1,$2...$n称为域标识。$0 为所有域,注意:此时和shell中变量$符含义不同
  文件的每一行称为记录
  省略action,则默认执行 print $0 的操作

示例:


取出第三列的域名

取分区利用率

取分区利用率并去掉%

一步直接取出df分区利用率

取/etc/passwd文件第一列和第三列

运算

awk变量

变量:内置和自定义变量

FS

输入字段分隔符,默认为空白字符
awk -v FS=':' '{print $1,FS,$3}' /etc/passwd
awk -F: '{print $1,$3,$7}' /etc/passwd

示例:


RS

输入记录分隔符,指定输入时的换行符
awk -v RS=' ' '{print }' /etc/passwd

ORS

输出记录分隔符,输出时用指定符号代替换行符
awk -v RS=' ' -v ORS='###' '{print $0}' /etc/passwd

示例

以冒号为分隔符,取第一个字符,默认换行

以等号为分隔符,不换行

NF

字段数量
awk -F:'{print NF}' /etc/fstab 引用变量时,变量前不需加$
awk -F:'{print $(NF-1)}' /etc/passwd

示例:

倒数第一个

-1倒数第二个

取出倒数第二个

进行排序

NR

记录号
awk '{print NR}' /etc/fstab ;
awk END '{print NR}' /etc/fstab

示例


$0打印所有字符,并添加编号

以冒号为分隔符,打印出文件内容,加上编号

FNR

各文件分别计数,记录号
awk '{print FNR}' /etc/fstab /etc/inittab
FILENAME:当前文件名
  awk '{print FILENAME}' /etc/fstab

ARGC

命令行参数的个数
awk '{print ARGC}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGC}' /etc/fstab /etc/inittab

ARGV

数组,保存的是命令行所给定的各参数
awk 'BEGIN {print ARGV[0]}' /etc/fstab /etc/inittab
awk 'BEGIN {print ARGV[1]}' /etc/fstab /etc/inittab

练习

自定义变量并运算

赋值并取出USER的值

赋值取出USER和UID的值

先变量后使用,不然会出现以下情况

printf命令

格式化输出:printf "FORMAT", item1, item2, ... 

(1) 必须指定FORMAT
(2) 不会自动换行,需要显式给出换行控制符,\n
(3) FORMAT中需要分别为后面每个item指定格式符

格式符:与item一一对应

%c:显示字符的ASCII码
%d, %i:显示十进制整数
%e, %E:显示科学计数法数值
%f:显示为浮点数
%g, %G:以科学计数法或浮点形式显示数值
%s:显示字符串
%u:无符号整数
%%:显示%自身

修饰符

#[.#] 第一个数字控制显示的宽度;第二个#表示小数点后精度,%3.1f

  • 左对齐(默认右对齐) %-15s
  • 显示数值的正负符号 %+d

示例

格式化输出

加n换行

取出分区利用率并且15个占位符后用冒号隔开

可以构建表格


操作符

算术操作符

x+y, x-y, x*y, x/y, x^y, x%y
-x:转换为负数
+x:将字符串转换为数值

字符串操作符

没有符号的操作符,字符串连接

赋值操作符:

=, +=, -=, *=, /=, %=, ^=,++, --
下面两语句有何不同
awk 'BEGIN{i=0;print ++i,i}'
awk 'BEGIN{i=0;print i++,i}'

比较操作符:

==, !=, >, >=, <, <=

模式匹配符:

~:左边是否和右边匹配,包含
!~:是否不匹配
示例:
awk -F: '$0 ~ /root/{print $1}' /etc/passwd
awk '$0~"^root"' /etc/passwd
awk '$0 !~ /root/' /etc/passwd
awk -F: '$3==0' /etc/passwd

示例:

实现条件过滤


打印20行之后的内容

打印出非#开头的行

取出IP地址

CentoS6的命令

逻辑操作符

与&&,或||,非!

示例:

awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd
awk -F: '$3==0 || $3>=1000 {print $1}' /etc/passwd
awk -F: '!($3==0) {print $1}' /etc/passwd
awk -F: '!($3>=500) {print $3}' /etc/passwd

示例

取出分区利用率在5到15之间的分区

后面每条命令都会处理一次

取出分区利用率大于5小于10的分区

取出分区利用率小于5的分区

条件表达式(三目表达式)

selector?if-true-expression:if-false-expression

示例:
awk -F: '{$3>=1000?usertype="Common User":usertype="SysUser";
printf "s:%-s\n",$1,usertype}' /etc/passwd

示例:

判断分区利用率,大于等于5的显示disk full,否则显示NOT FULL

过滤掉第一行

awk PATTERN

PATTERN:根据pattern条件,过滤匹配的行,再做处理
  • (1)如果未指定:空模式,匹配每一行
  • (2) /regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来
    awk '/^UUID/{print $1}' /etc/fstab
    awk '!/^UUID/{print $1}' /etc/fstab
  • (3) relational expression: 关系表达式,结果为"真"才会被处理
    真:结果为非0值,非空字符串
    假:结果为空字符串或0值
    示例:
    awk -F: 'i=1;j=1{print i,j}' /etc/passwd
    awk '!0' /etc/passwd ; awk '!1' /etc/passwd
    Awk -F: '$3>=1000{print $1,$3}' /etc/passwd
    awk -F: '$3<1000{print $1,$3}' /etc/passwd
    awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
    awk -F: '$NF ~ /bash$/{print $1,$NF}' /etc/passwd
  • (4) line ranges:行范围
    startline,endline:/pat1/,/pat2/ 不支持直接给出数字格式
    awk -F: '/^root\>/,/^nobody\>/{print $1}' /etc/passwd
    awk -F: '(NR>=10&&NR<=20){print NR,$1}' /etc/passwd
  • (5) BEGIN/END模式
    BEGIN{}:仅在开始处理文件中的文本之前执行一次
    END{}:仅在文本处理完成之后执行一次

示例:

取出以UUID开头的行

取不是以UUID开头的行

取出三个磁盘的利用信息

取出远程连接IP

取出连接三次以上的IP

找出远程连接三次以上的IP地址,视为**放进防火墙


不是空不是0就是真,是空的或者0就是假



取出文件中b到f开头的行

awk action

常用的action分类

  • (1) Expressions:算术,比较表达式等
  • (2) Control statements:if, while等
  • (3) Compound statements:组合语句
  • (4) input statements
  • (5) output statements:print等

awk控制语句

{ statements;… } 组合语句
if(condition) {statements;…}
if(condition) {statements;…} else {statements;…}
while(conditon) {statments;…}
do {statements;…} while(condition)
for(expr1;expr2;expr3) {statements;…}
break
continue
delete array[index]
delete array
exit

awk控制语句if-else

语法:

if(condition){statement;…}[else statement]
if(condition1){statement1}else if(condition2){statement2}else{statement3}

使用场景

对awk取得的整行或某个字段做条件判断

示例:

awk -F: '{if($3>=1000)print $1,$3}' /etc/passwd
awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
awk '{if(NF>5) print $0}' /etc/fstab
awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
awk -F: '{if($3>=1000) printf "Common user: %s\n",$1; else printf "root or Sysuser: %s\n",$1}' /etc/passwd
df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF>=80{print $1,$5}'
awk 'BEGIN{ test=100;if(test>90){print "very good"}
else if(test>60){ print "good"}else{print "no pass"}}'

示例:

判断分区利用率是否快慢,并且打印出利用率

用{}替换;

请提取".magedu.com"前面的主机名部分

awk控制语句

while循环

语法:while(condition){statement;…}

条件"真",进入循环;条件"假",退出循环

使用场景:

对一行内的多个字段逐一类似处理时使用
对数组中的各元素逐一处理时使用

示例:

  • awk '/^[[:space:]]*linux16/{i=1;while(i<=NF)
  • {print $i,length($i); i++}}' /etc/grub2.cfg
  • awk '/^[[:space:]]*linux16/{i=1;while(i<=NF)
  • {if(length($i)>=10){print $i,length($i)}; i++}}' /etc/grub2.cfg

for循环

语法

for(expr1;expr2;expr3) {statement;…}

常见用法

for(variable assignment;condition;iteration process) {for-body}

特殊用法

能够遍历数组中的元素 语法:for(var in array) {for-body}

示例

awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

示例:

用for循环运算1加到100

把文件每一段用空格隔开,合计每行每段有多少个字符

性能比较

分别用wak(for循环和while循环)和shell计算1加到100万的运算,并且看出awk时间短效率高

awk数组

关联数组:array[index-expression]

index-expression:

  • (1) 可使用任意字符串;字符串要使用双引号括起来
  • (2) 如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值 初始化为"空串"
  • (3) 若要判断数组中是否存在某元素,要使用"index in array"格式进行遍历
  • 示例:

    weekdays["mon"]="Monday"
    awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";
    print weekdays["mon"]}'
    awk '!line[$0]++' dupfile
    awk '{!line[$0]++;print $0, line[$0]}' dupfile

  • 若要遍历数组中的每个元素,要使用for循环
  • for(var in array) {for-body}
  • 注意:var会遍历array的每个索引
  • 示例:

    awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";
    for(i in weekdays) {print weekdays[i]}}'
    netstat -tan | awk '/^tcp/{state[$NF]++}
    END{for(i in state) { print i,state[i]}}'
    awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

awk函数

数值处理:

rand():返回0和1之间一个随机数
awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }'

字符串处理:

  • length([s]):返回指定字符串的长度
  • sub(r,s,[t]):对t字符串搜索r表示模式匹配的内容,并将第一个匹配内容替换为s
      echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)'
      echo "2008:08:08 08:08:08" | awk '{sub(/:/,"-",$1);print $0}'
  • gsub(r,s,[t]):对t字符串进行搜索r表示的模式匹配的内容,并全部替换为s所表示的内容
      echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)'
      echo "2008:08:08 08:08:08" | awk '{gsub(/:/,"-",$0);print $0}'
  • split(s,array,[r]):以r为分隔符,切割字符串s,并将切割后的结果保存至array所 表示的数组中,第一个索引值为1,第二个索引值为2,…
      netstat -tn | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}
        END{for (i in count) {print i,count[i]}}'

示例:

打印出TCP连接IP并统计连接次数


自定义函数格式

  function name ( parameter, parameter, ... ) {
    statements
    return expression
}
示例:
  cat fun.awk
  function max(x,y) {
    x>y?var=x:var=y
    return var
  }
  BEGIN{a=3;b=2;print max(a,b)}
  awk -f fun.awk

awk中调用shell命令

  • system命令
  • 空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用 空格分隔,或者说除了awk的变量外其他一律用""引用起来
      awk 'BEGIN{system("hostname") }'
      awk 'BEGIN{score=100; system("echo your score is " score) }'

awk脚本

  • 将awk程序写成脚本,直接调用或执行
  • 示例:
    cat f1.awk
      {if($3>=1000)print $1,$3}
    awk -F: -f f1.awk /etc/passwd
    .
    cat f2.awk
      #!/bin/awk -f
      #this is a awk script
      {if($3>=1000)print $1,$3}
    chmod +x f2.awk
    f2.awk -F: /etc/passwd

向awk脚本传递参数

格式:

awkfile var=value var2=value2... Inputfile

注意:

在BEGIN过程中不可用。直到首行输入完成以后,变量才可用。可以通 过-v 参数,让awk在执行BEGIN之前得到变量的值。命令行中每一个指定的变 量都需要一个-v参数

示例:

cat test.awk
#!/bin/awk -f
{if($3 >=min && $3<=max)print $1,$3}
chmod +x test.awk
test.awk -F: min=100 max=200 /etc/passwd

示例 字符 变量 字符串 处理 分隔符 利用率 格式 数组 命令 文件 循环 操作符 语句 元素 内容 字段 条件 模式 参数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发培训优势 怎么样查询网络安全考试成绩 数据库统计用户总数 重庆市分布式服务器云空间 sqlserver创建数据库语句 测试科学计算软件开发 视频存储服务器如何配置 打开数据库安全性 文明网络安全 班组网络安全文化建设方案 table循环填充数据库 肺小结节X片数据库 衡水秣马网络技术有限公司 湖州软件开发大概多少价格 往年网络技术应用会考题 徐州工业网络技术信息推荐 桦川软件开发设计在线咨询 2018国家网络安全主题是 淄博联想服务器总代理批发 软件开发的工具及作用 与服务器连接中断请稍后再试联接 网络安全技术与应用 官网 网络安全工作荣誉 数据库字符串转换数字类型 工业企业数据库包括上市公司吗 数据库 手机号码 安全吗 战地1怎么选服务器 怀旧服服务器维护工程师 数据库设计表只有一个主键 茂名卫星软件开发厂家直销
0