Linux - Awk 用法

Awk语言基础教程
  0.Awk 有三个不同的版本awk,nawk 和gawk,未作特别说明,一般指gawk。
  1.Awk语言的最基本功能是在文件或字符串中基于指定的规则来分解抽取信息,也可以基于指定的规则来输出数据。完整的awk脚本通常用来格式化文本文件中的信息。
  2.三种方式调用awk 1) awk [option] 'awk_script' input_file1 [input_file2…] awk的常用选项option有:
  -F fs:使用fs作为出入记录的字段分隔符,如果省略该选项,awk使用环境变量IFS的值
  -f filename:从文件filename中读取awk_script
  -v var=value:为awk_script设置变量 2)将awk_script放入脚本文件并以#!/bin/awk f为首行 ,给予该脚本可执行权限,然后再shell下通过键入该脚本的脚本名调用之。 3) awk [options] -f scriptfile var=value file(s) 3. awk的运行过程
  1)awk_script的组成
  Awk_script可以由一条或多条awk_cmd组成,两条awk_cmd之间一般以NEWLINE分隔
  Awk_cmd由两部分组成:awk_pattern{actions}
  Awk_script 可以被分成多行书写,必须确保整个awk_script被单引号括起来
  2) awk的一般命令形式
  awk 'BEGIN{actions} \
  awk_pattern1{actions} \
  >awk script
  Awk_patternN{actions} /
  END{actions} /
  'inputfile
  其中,BEGIN{actions}和END{actions}是可选的。
  3) awk的运行过程:
  ①如果BEGIN区块存在,awk执行它指定的actions。
  ②Awk从输入文件中读取一行,成为一条输入记录。(如果输入文件省略,将从标准输入读取);
  ③Awk将读入的纪录分隔成字段,将第1个字段放入变量 $1,第二个字段放入$2,依次类推。$0表示整条记录。字段分隔符使用shell环境变量IFS或由参数指定。
  ④把当前输入记录一次与每一个awk_cmd中的awk_pattern比较,看是否匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直掉比较完所有的awk_cmd。
  ⑤当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复步骤③④,这个过程持续,直掉awk读取到文件尾。
  ⑥当awk读完所有的输入行后,如果存在END,就执行相应的actions。
  4) input_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。
  5) 一条awk_cmd的awk_pattern可以省略,省略时部队输入记录进行匹配比较执行相应的acitons。一条awk_cmd的actions也可以省略,省略时默认的动作作为打印当前输入记录(print$0)。一条awk_cmd中的awk_pattern和actions不能同时省略。
  6) BEGIN区块和END区块分别位于awk_script的开头和结尾。Awk_script中的只有END区块或者只有BEGIN区块是被允许的。如果awk_script中只有BEGIN{actions},awk不会读取input_file。
  7) Awk把输入文件的数据读入内存,然后操作内存中的输入数据副本,awk不会修改输入文件的内容。
  8) Awk的总是输出到标准输出,如果想让awk输出到文件,可以使用重定向。
  3. Awk_pattern
  Awk_pattern模式部分决定actions动作部分合式触发及触发acitions。Awk_pattern可以是以下几种类型
  1) 正则表达式用作awk_pattern:/regexp/
  ① awk中则正则表达式匹配操作中经常用到的字符:\ ^ $ . [] | () *//通用的regexp元字符;+:匹配其前的单个字符一次以上,使awk自有的元字符,不适用于grep或sed等;?:匹配其前的单字符1次或0次,使awk自有的元字符,不适用于grep或sed等
  ② 举例:awk'/*\$0\.[0-9][0-9].*/' input_file
  1) 布尔表达式用作awk_pattern,表达式成立时,触发相应的actions执行。
  ① 表达式中可以使用变量(如字段变量$1,$2等)和/regexp/
  ② 布尔表达式的操作符:
  关系操作符: = = = !=
  匹配操作符: value ~/regexp/ 如果value匹配/regexp/,则返回真
  value !~ /regexp/ 如果value不匹配/regexp/,则返回真
  举例:awk '$2>10{print "ok"}' input_file
  awk '$3~ /^d/{print "ok"}' input_file
  ③ &&(与)和||(或)可以连接两个/regexp/或者布尔表达式,构成混合表达式。!(非)可以用于布尔表达式或者/regexp/之前。举例awk '/^d/||/x$/{print "ok" input_file
  ③ 其他表达式用作awd_script如赋值表达式等
  Awk '(tot+=$6);END{print "total points:"tot"} input_file //分号不能省略
  Awk 'tot+=$6{print $0}END{print "total points:"tot}' input_file //与上面等效
  2. actions
  \actions就是对awk读取的记录数据进行的操作。Actions由一条或者多条命令。参数列表要用分号号(;)分隔。Actions中还可已使用流程控制结构的语句。
  1) awk的命令:
  ① print参数列表: print可以打印字符串(加双引号),变量和表达式,是awk最基本的命令。参数列表要用逗号(,)分隔,打印出时参数值之间不会有空格。
  ② printf([格式控制符],参数):格式化打印命令(函数),语法与C语言的printf函数类似
  ③ next:强迫awk立刻停止处理当前的记录,而开始读取和处理下一条记录。
  ④ nextfile:强迫awk立刻停止处理当前的输入文件而处理输入文件列表中的下一个文件
  ⑤ exit:使awk停止执行而跳出。如果END存在,awk回去执行END的actions。
  2) awk的语句: awk的语句只要是赋值语句,用来给变量赋值。
  ① 把直接值或一个变量值赋值给变量。如果直接值是字符串要加双引号。
  举例:awk'BEGIN{x=1;y=3;x=y;print"x=";y="y}'
  ② 把一个表达式的值赋值给变量。表达式一般式数值表达式,也可是其他表达式。
  数值表达式:num1 operator num2
  Operator可以是+(加)-(减)*(乘)%(取余)^(求幂)
  当num1或者num2是字符串而逝不是数组时,无论是否加有双引号,awk都视其值为0
  条件选择表达式A?B:C(A为不二表达式,B和C可以是表达式或者直接值)
  当布尔表达式A的值为真时,整个表达式的值为B,A的值为假是,整个表达式的值为
  C
  Awk 'BEGIN{x=3;y=x>4?"ok":4;print"x=";y="y}' ③为了书写方便,awk也支持c语言语法的赋值操作符:+= -= *= /= ^= ++ - -
  2) 流程控制结构(基本上是使用c语言的语法)
  其中condition一般为布尔表达式,body和else-body是awk语句块。
  ① if(condition){then-body}[else{else-body}]
  ② while(condition){body}
  ③ do{body}while(condition)
  ④ for(initialization;condition; increment) {body}与c语言的for结构相同。
  ⑤ break和continue
<think> 我们正在讨论的是Linux系统中的awk命令使用方法。根据用户提供的参考资料,我们可以系统地介绍awk用法。 注意:用户要求使用特定格式回答,包括数学表达式的格式,以及生成相关问题。同时,需要参考之前提供的引用内容。 回答结构: 1. 介绍awk的基本概念和用途。 2. 详细讲解awk的基本语法和核心概念(内置变量、分隔符、BEGIN和END块)。 3. 常见用法示例(基础打印、条件过滤、计算与统计、字符串操作、处理CSV文件)。 4. 高级用法(数组统计、多条件分支、结合外部命令、自定义函数)。 5. 实战场景示例(分析Nginx访问日志、提取特定时间段日志、生成格式化报告)。 6. 常用技巧和性能优化。 7. 生成相关问题。 注意:在回答中使用LaTeX格式的数学表达式(如果有的话),但根据内容,awk中可能较少涉及数学公式,但如果有计算类的内容,我们按照要求书写。 另外,在适当的地方添加引用标记(如[^1]、[^2]等),这些引用标记对应到用户提供的引用内容。 由于用户提供了多个引用,我们在讲解时会参考引用内容,并在相关位置标注。 开始回答: </think> ### Linux 系统 awk 命令使用详解 awkLinux 文本处理的「三剑客」之一(与 sed/grep 齐名),专精结构化数据提取与统计。核心原理是**逐行扫描文件,按规则处理字段**,以下是系统级使用指南: --- #### **一、基础语法结构** ```bash awk [选项] '模式 {动作}' 文件名 ``` - **模式**:行筛选条件(如 `$2>10`) - **动作**:处理命令(如 `{print $1,$3}`) - **常用选项**: `-F` 指定分隔符(默认空格/Tab) `-v` 定义变量(如 `-v OFS="|"` 设置输出分隔符)[^2][^3] --- #### **二、核心概念及操作** 1. **内置变量** | 变量 | 含义 | 示例 | |------|-----------------------|--------------------------| | `NR` | 当前行号 | `awk '{print NR,$0}'` | | `NF` | 当前行列数 | `awk '{print $NF}'` | | `FS` | 输入字段分隔符 | `BEGIN{FS=":"}` | | `OFS`| 输出字段分隔符 | `BEGIN{OFS="-"}` | | `FILENAME` | 当前文件名 | `END{print FILENAME}` | 2. **BEGIN/END 块** - 预处理:`BEGIN{}` 在读取文件前执行(如初始化变量) - 后处理:`END{}` 在文件处理后执行(如汇总统计)[^4] ```bash awk 'BEGIN{sum=0} {sum+=$3} END{print "总和:" sum}' data.txt ``` 3. **多分隔符处理** ```bash # 同时识别空格/斜线/冒号为分隔符(连续视为一个) echo "id:100 /name=john" | awk -F '[: /=]+' '{print $2,$4}' # 输出:100 john ``` 此技巧常用于日志解析(如 Nginx/IP 命令输出)[^3] --- #### **三、高频使用场景示例 ▎1. 基础字段提取 ```bash # 提取 /etc/passwd 的用户名和 UID awk -F: '{print $1 "的ID是:" $3}' /etc/passwd # 输出第2列大于10的行(逗号输出用OFS分隔) awk -v OFS=" | " '$2 > 10 {print NR, $1,$2}' data.txt ``` ▎2. 条件过滤与计算 ```bash # 统计CPU使用率>80%的进程数量 ps aux | awk '$3 > 80 {count++} END{print count}' # 计算文件总大小(第5列为大小) ls -l | awk 'BEGIN{sum=0} {sum+=$5} END{print sum/1024 "KB"}' ``` ▎3. 字符串操作 ```bash # 替换字段内容(将第2列的old替换为new) awk '{gsub("old","new",$2); print}' file.txt # 提取IP地址(匹配数字+点号格式) ip a | awk '/inet / {match($2,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/); print substr($2,RSTART,RLENGTH)}' ``` ▎4. 日志分析实战 ```nginx # Nginx日志格式:172.17.0.1 - - [05/May/2023:10:30:22 +0800] "GET /api HTTP/1.1" 200 612 ``` ```bash # 统计每小时请求量 awk -F'[: ]' '{count[$3]++} END{for(h in count) print h "时: " count[h] "次"}' access.log # 提取特定时间段日志(10:30-11:30) awk -F'[: ]' '$3=="10" && $4>=30 || $3=="11" && $4<=30' access.log ``` --- #### **四、高级技巧** 1. **数组统计** ```bash # 统计单词频率(忽略大小写) awk '{for(i=1;i<=NF;i++) count[tolower($i)]++} END{for(word in count) print word, count[word]}' text.txt ``` 2. **多分支逻辑** ```bash awk '{ if ($3 >= 90) grade="A"; else if ($3 >= 80) grade="B"; else grade="C"; print $1, grade }' scores.txt ``` 3. **性能优化建议** -文件处理时避免 `print $0`,明确指定输出字段 - 使用 `next` 跳过无关行(如 `/error/ {print; next}`) - 复杂操作优先用内置函数(如 `gsub()` 比管道 `sed` 高效) --- ### 相关问题 1. 如何用 `awk` 实现两个文件的关联查询? 2. `awk` 如何处理带换行符的 JSON 日志? 3. `awk` 与 `Python` 处理 GB 级文本的性能对比? 4. 如何用 `awk` 生成 HTML/CSV 格式报告? > 深入学习:执行 `man awk` 或参考 [GNU Awk 手册](https://www.gnu.org/software/gawk/manual/)。实战案例可延伸阅读《Shell脚本学习指南》[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值