Shell编程基础(十六)文本三剑客(awk & cut)

awk

使用场景

前面的 grep 和 sed 在处理文本时都是以行为单位,逐行处理;还有很多其他的命令都是以行为单位进行处理。
在实际开发运维中,可能需要拆分整行内容,只关心部分字段。可以使用awk进行拆分,而且awk也支持行数据过滤

简单来说 awk ≈ grep + cut

基本使用

与 grep,sed类似;awk 可以直接从文件获取数据也可以从管道流获取数据

  • 基本语法
    awk [opts] ‘commands’ file
    cat file | awk [opts] ‘commands’

  • opts
    常用参数

    • -F 指定分隔符
    • -v 定义一个能在后面脚本中使用的变量,脚本中引用时直接写变量名,无需$因为awk 脚本内无法直接引用外部变量
      awk 内置常用变量:NF(当前行拆分后的列数),NR(行号)
      FILENAME(当前处理的文件名)
  • commands 类型
    分为 前置命令BEGIN{},中间命令{},后置命令END{}
    前置命令和后置命令只会在处理文件开始和结束时执行依次,而中间命令则会应用到每一行数据,有点类似Junit测试的 @BeforAll @Test @AfterAll 的关系

  • awk 处理文件方式
    awk获取到文件内容后,也是一行一行处理,它会以指定分隔符(默认为空格,可通过-F 自定分隔符)将每一行数据拆分成多个字段
    $0 代表整行数据,$1…后面依次代表每个字段

awk的功能非常丰富,它作为一门独立的变成语言

  • awk 过滤数据
    awk 也支持过滤数据;它既支持整行的正则匹配,也支持拆分后的词单项比较或者正则匹配
    而且它支持各种比较运算符以及正则表达式(使用 /express/ 匹配拆分后词;使用 ~,取反 !~)

实例

参数使用
  • 使用 -F 和 -v
# 以 / 为分隔符,自定义参数 x=123
awk -F / -v x=123 '{print $1, x}'
  • 创建 student.txt 文件
编号    姓名    性别    年龄
1       张三    男      11
2       李四    女      9
3       王五    男      17
4       赵六    男      22
5       刘胜男  女      15
6       王小二  男      9
7       张三疯  男      125
  • 获取所有学生id
awk '{print $1}' student.txt
编号
1
2
3
4
5
6
7
  • 去掉上面的表头
awk '$1 != "编号" {print $1}' student.txt
1
2
3
4
5
6
7
  • 查看性别为男的学生信息
awk '$3 == "男"' student.txt

1       张三    男      11
3       王五    男      17
4       赵六    男      22
6       王小二  男      9
7       张三疯  男      125
  • 查看性别为男的学生姓名和年龄
awk '$3 == "男" {print $2"\t"$4}' student.txt

张三    11
王五    17
赵六    22
王小二  9
张三疯  125
  • 查看姓名以张开头的学生信息
awk '$2 ~ /^张/' student.txt
1       张三    男      11
7       张三疯  男      125

表头被过滤掉了… 加上表头

awk '$2 ~ /^[张(姓名)]/' student.txt
编号    姓名    性别    年龄
1       张三    男      11
7       张三疯  男      125

还可以这样,使用 | 替代 []

awk '$2 ~ /^张|姓名/ ' student.txt
编号    姓名    性别    年龄
1       张三    男      11
7       张三疯  男      125
  • 查看姓名以张开头的学生信息
    姓名也不以张开头,直接显示出来了,无需再单独处理
awk '$2 !~ /^张/' student.txt
编号    姓名    性别    年龄
2       李四    女      9
3       王五    男      17
4       赵六    男      22
5       刘胜男  女      15
6       王小二  男      9
  • 查找姓张,名只有一个字的学生&带上表头
awk '$2 ~ /^张.$|姓名/' student.txt
编号    姓名    性别    年龄
1       张三    男      11
  • 按正则表达式过滤,提取部分字段
awk '$2 ~ /^张.$|姓名/ {OFS="\t"; print $1, $2, $4}' student.txt
编号    姓名    年龄
1       张三    11


awk '$2 ~ /^张.$|姓名/ {print $1"\t"$2"\t"$4}' student.txt
编号    姓名    年龄
1       张三    11


awk '$2 ~ /^张.$|姓名/ {print $1 "\t" $2 "\t" $4}' student.txt
编号    姓名    年龄
1       张三    11

各种匹配方式可结合正则实现

给指定登录当前主机的用户发送消息
#!/bin/bash

# 校验参数
if [[ -z $1 ]]
then
echo "接收用户不能为空"
exit 2
fi

#校验用户是否在线 并且支持消息通讯
login=`who -T | awk -v receive_user=$1 '$1 == receive_user && $2 == "+"'`

if [[ -z login ]]
then
echo "用户当前无法接收消息"
fi

write `echo $login | awk '{print $1 " " $3}'`

cut

功能与awk 类似,都是提取列
常用参数

  • -f :取第几列
    固定列 用逗号(,)隔开 -f 1,2,3
    范围列 用 - 连接,没有边界的那一端不写
  • d:分隔符(默认以空格分割,与awk一样)
  • c:按字符拆分;取 几个字符 -c 10取前10个字符
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值