前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >上古神器 awk 笔记

上古神器 awk 笔记

作者头像
菜菜cc
发布2022-11-15 21:38:05
1.7K0
发布2022-11-15 21:38:05
举报
文章被收录于专栏:菜菜的技术博客

awk基本格式

代码语言:javascript
复制
awk '{ awk program }' file

file 为 awk 要读取的文件,可以是一个或多个文件。如果不指定文件,则从标准输入中读取

代码语言:javascript
复制
awk '{ awk program }' a.txt b.txt c.txt

单引号内的是awk的程序,一般使用单引号而非双引号。 awk是按行处理文件,内部有一个隐藏的循环,即默认下逐行读取文件并运行程序

使用单引号原因:双引号中的$会被 shell 解析成 shell 变量引用,于是会进行 shell 变量替换。为了表示awk程序使用的变量,所以尽可能使用单引号

awk 程序中的 {} 表示代码块

代码语言:javascript
复制
awk '{print $0}' a.txt
awk '{print $0}{print $0; print $0}' a.txt

BEGINEND 语句块

代码语言:javascript
复制
awk 'BEGIN{print "俺要开始读文件啦"}{print $0}END{print "俺处理完文件啦"}' a.txt
  • BEGIN 代码块: 在读取文件前行执行一次,不参与awk的隐藏循环
  • END 代码块: 在读取文件完成后执行一次,不参与awk的隐藏循环
  • main 代码块:不以BEGINEND开头的代码块都称之为 main 代码块, main 代码块会参与 awk 的隐藏循环

awkpattern 和 action

代码语言:javascript
复制
awk '
BEGIN {
    n=3
}
/^[0-9]/ {
    print $1
}
END {
    print "end"
}
' a.txt

awk语法格式为pattern { action }模式, 称之为awkrule

  • pattern 用于筛选符合的文本行
  • action 表示筛选通过后执行的操作
  • pattern 和 action 都可省略
    • 省略 pattern 则不筛选数据,表示对每一行数据都执行 action
    • 省略 {action} 表示对每一行都执行 {print}
    • 省略 action 表示对筛选的行不做任何操作,该语法实际使用中并无意义

可以将 BEGIN 与 END 代码块看成一种特殊的 pattern{action} 代码块

代码语言:javascript
复制
# bool pattern
/regular expression/   # 正则匹配,e.g., /a.*ef/{action}
relational expression  # 大小关系匹配,e.g., 3>2{action}
pattern && pattern     # 逻辑与
pattern || pattern     # 逻辑或
!pattern               # 逻辑反
pattern ? pattern : pattern  # 三目运算符

# 范围 pattern
pattern1, pattern2     # 范围匹配,匹配从 pattern1 到 pattern2 之间的内容

awk 读取文件

记录分隔符

awk读取文件时, 每读取一条记录(Record)(默认下按行读取,一行就是一条记录). 每读取一条记录,将其保存到$0中,然后执行一次 main 代码段。

可通过修改预定义变量RS来改变每次读取的记录模式,RS变量表示输入记录分隔符(Record Separator),默认值为\n

RS一般设置在 BEGIN 代码块中,因为需要在读取文件前确定好分隔符

注:RS变量作为输入记录分割符,所读取的每条记录不包含RS变量值

  • RS 为单个字符, 则直接用该字符来分割记录
  • RS 为多个字符,则将其作为正则表达式,只要匹配上正则表达式都用来分割记录
    • 设置预定义变量IGNORECASE为非零值,正则匹配时忽略大小写

特殊RS值解决特定需求:

代码语言:javascript
复制
RS=""    # 按段落读取
RS="^$"  # 一次性读取所有数据, 该正则只能匹配空文件
RS="\n+" # 按行读取,但忽略所有空行

awk每读取一条记录时,会设置预定义变量RT表示记录分割符(Record Termination)。 当RS为单个字符时,RT的值和RS值相同。 当RS为正则表达式时,RT`为正则匹配的记录分隔符

行号

awk读取每条记录后,将其赋值给$0和设置RT外,还会设置NRFNR这两个预定义变量

  • NR: 所有文件的行号计数器
  • FNR: 各个文件的行号计数器,针对于多个文件输入的情况

字段分割

awk读取每条记录后,将其赋值给0,同时还会对该条记录按照预定义变量FS划分字段,将划分后的各个字段依次存入 1,2, 3 …,同时将划分好的字段数量赋值给预定义变量NF

代码语言:javascript
复制
awk '{print $NF}' a.txt   # 输出 a.txt 的最后一列

未完待续 ~~

本文作者: Ifan Tsai  (菜菜)

本文链接: https://cloud.tencent.com/developer/article/2164605

版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • awk基本格式
  • BEGIN 和 END 语句块
  • awkpattern 和 action
  • awk 读取文件
    • 记录分隔符
      • 行号
        • 字段分割
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档