# AWK
awk '{pattern + action}' filenames
# 1. 执行方式
# 1.1. 命令行:
awk [-F field-separator] 'commands' inputfile(s)
# 1.2. 脚本方式:
#!/bin/awk
……
# 1.3. 文件方式:
awk -f awk-script-file input-file(s)
# 2. 变量和函数
# 1.内置变量
| 名称 | 说明 |
|---|---|
| ARGC | 命令行参数个数 |
| ARGV | 命令行参数排列 |
| FS | 设置输入域分隔符,等价于命令行 -F选项 |
| RS | 控制记录分隔符 |
| FNR | 浏览文件的记录数 |
| NF | 浏览记录的域的个数 |
| NR | 已读的记录数 |
| OFS | 输出域分隔符 |
| ORS | 输出记录分隔符 |
| ENVIRON | 支持队列中系统环境变量的使用 |
| FILENAME | awk浏览的文件名 |
# 2.内置函数
# split
把一个字符串分隔为单词并存储在数组中。使用自定义域分隔符或者FS(域分隔符)的值。
- split (string, array, field separator)
- split (string, array)
如
awk '{split($0,a,":");print a[1],a[2],a[3]}'
# substr
返回从起始位置起,指定长度之子字符串;若未指定长度,则返回从起始位置到字符串末尾的子字符串。
- substr(s,p) 返回字符串s中从p开始的后缀部分
- substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
# gsub
替换所有正则表达式匹配的部分
- gsub(regular expression, subsitution string,target string)
如
gsub("abc", "def", $0) # $0的abc都替换成def
# 3.编程
awk 'BEGIN{} {pattern + action} END{}' filename
# 条件:
if (expression) {
statement1;
} else if (expression1) {
statement2;
} else {
statement3;
}
# 循环:
while (true){
}
do {
continue
}while(true)
for (i =0; i < 10;i++){
break
}
# 关联数组:
awk -F':' 'BEGIN {count=0;} {name[count] = $1;count++;} END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
# 4. 实例
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
每行数据按模版生成文件
- 定义变量
BEGIN {
FS=",";
template="email_template.txt";
output="acceptance";
getline;
NR=0;
}
getline会读取一行数据,NR=0可以重置记录数,这样可以跳过开头一行
- 处理每行数据
包括解析变量,读取模版每一行,替换变量,输出文件
{
# 从输入文件中读取关联字段
firstname=$1;
lastname=$2;
email=$3;
title=$4;
# 设置输出文件名
outfile=(output NR ".txt");
# 从模板中读取一行,替换特定字段,
while ( (getline ln < template) > 0 )
{
sub(/{firstname}/,firstname,ln);
sub(/{lastname}/,lastname,ln);
sub(/{email}/,email,ln);
sub(/{title}/,title,ln);
# 并打印结果到输出文件
print(ln) > outfile;
}
# 关闭模板和输出文件,继续下一条记录
close(outfile);
close(template);
}
- 运行脚本
awk -f script_file_name.awk proposals.csv
awk -f script_file_name.awk < proposals.csv