awk用法
awk是一种强大的文本处理工具,用于在Unix/Linux环境下处理和分析文本文件。以下是awk的一些常用用法以及示例。
基本用法
awk的基本语法如下:
awk 'pattern {action}' filename
pattern是一个模式,action是在模式匹配时执行的动作。
打印文件的每一行
awk '{print}' filename
此命令将打印文件的每一行。
打印指定行
假设有一个名为file.txt的文件,内容如下:
Alice 23
Bob 30
Charlie 25
打印第二列(年龄):
awk '{print $2}' file.txt
输出:
23
30
25
条件匹配
打印年龄大于25的行:
awk '$2 > 25 {print}' file.txt
输出:
Bob 30
使用内置变量
awk有一些常用的内置变量:
- NR:当前记录数
- NF:当前记录中的字段数
打印行号和对应行:
awk '{print NR,$0}' file.txt
输出:
1 Alice 23
2 Bob 30
3 Charlie 25
打印每行的字段数:
awk '{print NF}' file.txt
输出:
2
2
2
使用BEGIN和END块
在处理之前和处理之后执行一些命令:
awk 'BEGIN {print "Start"} {print} END {print "End"}' file.txt
输出:
Start
Alice 23
Bob 30
Charlie 25
End
字符串匹配
打印包含"Alice"的行:
awk '/Alice/ {print}' file.txt
输出:
Alice 23
数学运算
假设有一个numbers.txt文件,内容如下:
10
20
30
40
计算这些数字的总和:
awk '{sum += $1} END {print sum}' numbers.txt
输出:
100
格式化输出
使用printf进行格式化输出:
awk '{printf "Name: %s,Age: %d\n",$1,$2}' file.txt
输出:
Name: Alice, Age: 23
Name: Bob, Age: 30
Name: Charlie, Age: 25
多个条件和动作
处理多个条件和对应的动作:
awk '$2 < 25 {print $1 " is young"} $2 >= 25 {print $1 " is old"}' file.txt
输出:
Alice is young
Bob is old
Charlie is old
使用用户定义变量
使用用户定义的变量来存储中间结果:
awk '{count++} END {print "Total:",count}' file.txt
输出:
Total: 3
使用外部变量
从外部传递变量给awk:
age=25
awk -v age=$age '$2 > age {print $1 " is older than " age}' file.txt
输出:
Bob is older than 25
Charlie is older than 25
多个文件处理
awk可以处理多个文件,并能够识别不同文件中的行:
awk 'FNR==1 {print "Processing " FILENAME} {print}' file1.txt file2.txt
此命令在处理每个文件的第一行时打印文件名。
多条件匹配
通过&&和||进行多条件匹配
awk '$2 > 20 && &2 < 30 {print $1 " is in twenties"}' file.txt
此命令将打印年龄在20到30之间的人名。
自定义函数
在awkzh用定义并调用自定义函数:
awk 'function myfunc(x) {return x*x} {print $1,myfunc($2)}' file.txt
此命令将打印每个人的名字和年龄的平方。
正则表达式匹配
复杂的正则表达式匹配:
awk '/[A-Z][a-z]+/ {print}' file.txt
此命令将打印包含大写字母开头、后跟小写字母的单词的行。
复杂的文本处理
假设有一个CSV文件data.csv,内容如下:
Name, Age, Department
Alice, 23, HR
Bob, 30, Engineering
Charlie, 25, Marketing
打印所有部门是"Engineering"的人员信息:
awk -F ", " '$3 == ""eNGINEERING {print $1,$2}' data.csv
输出:
Bob 30
使用数组
awk中的数组可以用于复杂的数据存储和处理:
awk '{arr[$3]++} END {for (dept in arr) print dept,arr[dept]}' data.csv
此命令将打印每个部门的人员数量。
处理分隔符
处理不同分隔符的文件:
awk -F "|" '{print $1,$3}' file_with_pipes.txt
此命令将使用|作为字段分隔符,并打印第1和第3列。
多行处理
跨行处理数据,例如连接多行内容:
awk '{if (NR%2 == 1) printf $0 " ";else print $0}' file.txt
此命令将两行合并成一行。
高级输出格式化
生成复杂的格式化输出,例如生成HTML列表:
awk 'BEGIN {print "<ul>"} {print "<li>" $1 "</li>"} END {print "</ul>"}' file.txt
输出:
<ul>
<li>Alice</li>
<li>Bob</li>
<li>Charlie</li>
</ul>
使用外部命令
结合awk和其他命令的输出:
ls -l | awk '{print $9,$5}'
此命令将列出当前目录中每个文件的名称和大小。
复杂数据统计
对复杂数据进行统计分析:
awk '{sum+=$2;count++} END {print "Average:", sum/count}' file.txt
此命令计算第二列的平均值。
综合示例
假设有一个日志文件log.txt,内容如下:
2024-01-01 10:00:00 User1 action1
2024-01-01 10:05:00 User2 action2
2024-01-01 10:10:00 User1 action3
2024-01-01 10:15:00 User2 action1
统计每个用户的活动次数:
awk '{user[$2]++} END {for (u in user) print u,user[u]}' log.txt
输出:
User1 2
User2 2
复杂文件处理
假设有一个复杂的文本文件complex.txt,其中包含嵌套结构的数据:
{
"name": "Alice",
"age": 23,
"skills": ["C", "C++", "Java"]
}
{
"name": "Bob",
"age": 30,
"skills": ["Python", "Go", "Rust"]
}
提取所有用户的名字和技能:
awk '/"name":/ {name=$2} /"skills":/ {gsub(/[\[\]"]/,"",$3); skills=$3} /}/ {print name, skills}' complex.txt
输出:
"Alice", C, C++, Java
"Bob", Python, Go, Rust
以上示例展示了awk在处理多种数据和文本分析任务中的强大能力。通过灵活运用awk的模式匹配、内置函数、数组和用户自定义函数等特性,可以实现各种复杂的文本处理需求。