文章目录
  • awk把连续的相同的分隔符作为1个分隔符处理!
  • awk可以按分隔符对每行进行切片处理!
  • awk会循环处理文件的每一行,这点与sed类似!
#
# options
#
# -f scripfile  可指定要执行的脚本文件.内容如:BEGIN{} {} END{}
# -F:  指定域分隔符为冒号,注意他们之间没有空格

#
# environment
#
# $n: 表示第1、第2...n个域
# $0: 表所有的域,类似于数据库中的一行Record(记录)
# FIELDWIDTHS: 如指定FIELDWIDTHS="2 3"表示第1列占2两个字符,第2列占3个字符!
# FS: 字段分隔符,默认是空格;OFS:输出字段分隔符;
# RS: 输入数据行分隔符,默认是换行;如果写成""则表示空白行,通常配合FS="\n"使用!
# NF: 数据文件中的字段总数!$NF就表示最后一个字段!$(NF-1):倒数第二。
# NR: 当前已处理的记录数!第2行时为2...
# ARGC: 命令行参数的数量
# ARGV: 命令行参数的数组
# ERRNO: 最后一个系统错误的描述
# CONVFMT: 数字格式转换
# FILENAME: 当前文件名 

# 命令必须放在大括号中,多个命令使用分号';'或换行符分割.
# 数组的下标可以看成是字符串,故`arr[09]`与`arr[9]`是不同的.
awk [options] '{program}' file

# awk会在每读取一行数据后,调用命令处理.
# 如下可以在所有事情之前执行cmd1,然后使用cmd做正事.完事后执行cmd2.
awk 'BEGIN {cmd1 FS=":"} {cmd} END {cmd} file'

# 逐行读取并切片,默认域分隔符是空格.
# ~/pattern/:匹配正则表达式; !~/pattern/:不匹配正则表达式
awk -F: '/pattern/{command}' file

function

  sub(r,s,t)    # 在t中将第一次出现的r替换为s
  substr(r,s)   # r中s开始的后缀部分
  substr(r,s,t) # r中s开始长度为t的后缀部分
  gsub(r,s)     # 在输入文件中用s替换r
  gsub(r,s,t)   # 在t中用s替换r
  index(s,t)    # s中第一个字符串t的位置
  length(s)     # s的长度
  match(s,t)    # s中是否包含匹配t的字符串,返回出现位置的索引+1,没有时返回0
  split(r,s,t)  # 在t上将r按s分割成序列
  if (condition)  # if (x~/[Hh]el?o/),使用正则表达式
    actions
  else
    actions
  while (condition)
    actions
  do
    actions
  while (condition)
  for (init_val; test_val; change_val)
    actions
  for (var in array)
    actions

demo

  awk '{print $2 $1 $4 $3}' file  # 打印file中的2,1,4,3列
  awk -F ":" '{if ($1==2 && $2==$3) printf $0}' /etc/passwd
  awk 'BEGIN {FS=","} {printf("%s\t%d\n",$2,$8)}' file  # 每输出两个域后换行
  awk 'BEGIN {FS=":";OFS=":"} gsub(/root/,"ROOT",$1) print $0' /etc/passwd  # 替换后输出
  awk 'NR % 2 == 0' xx  # 打印偶数行