# 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

每行数据按模版生成文件

  1. 定义变量
BEGIN {
  FS=",";
  template="email_template.txt";
  output="acceptance";
  getline;
  NR=0;
}

getline会读取一行数据,NR=0可以重置记录数,这样可以跳过开头一行

  1. 处理每行数据

包括解析变量,读取模版每一行,替换变量,输出文件

{
    # 从输入文件中读取关联字段
    firstname=$1;
    lastname=$2;
    email=$3;
    title=$4;
    # 设置输出文件名
    outfile=(output NR ".txt");
    
    # 从模板中读取一行,替换特定字段,
    while ( (getline ln &lt; template) &gt; 0 )
    {
            sub(/{firstname}/,firstname,ln);
            sub(/{lastname}/,lastname,ln);
            sub(/{email}/,email,ln);
            sub(/{title}/,title,ln);
            # 并打印结果到输出文件
            print(ln) &gt; outfile;
    }
    # 关闭模板和输出文件,继续下一条记录
    close(outfile);
    close(template);
}
  1. 运行脚本
awk -f script_file_name.awk proposals.csv
awk -f script_file_name.awk  < proposals.csv