【无标题】

**

-awk

**
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势

常用命令选项

  • -F fs:fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
  • -v var=value:赋值一个用户定义变量,将外部变量传递给awk
  • -f scripfile:从脚本文件中读取awk命令

awk变量
变量:内置和自定义变量,每个变量前加 -v 命令选项
内置变量

  • FS输入字段分隔符默认为空白字符
  • OFS输出字段分隔符,默认为空白字符
  • RS :输入记录分隔符,指定输入时的换行符,原换行符仍有效
  • ORS :输出记录分隔符,输出时用指定符号代替换行符
  • NF :字段数量,共有多少字段, N F 引用最后一列, NF引用最后一列, NF引用最后一列,(NF-1)引用倒数第2列
  • NR行号,后可跟多个文件,第二个文件行号继续从第一个文件最后行号开始
  • FNR :各文件分别计数, 行号,后跟一个文件和NR一样,跟多个文件,第二个文件行号从1开始
  • FILENAME :当前文件名
  • ARGC :命令行参数的个数
  • ARGV :数组,保存的是命令行所给定的各参数,查看参数

自定义变量
(1)-v var=value
(2)在program 中直接定义

  1. 插入几个新字段
    在"a b c d"的b后面插入3个字段e f g
echo "a b c d" | awk '{$2=$2" e f g";print}'

2.取字段中指定字符数量
数据:

16  001agdcdafasd
16  002agdcxxxxxx
23  001adfadfahoh
23  001fsdadggggg

想得到:
16  001
16  002
23  001
23  002

awk字符索引从1开始
awk '{print $1,substr($2,1,3)}'
利用FIELDWIDTH分割
awk 'BEGIN{FIELDWIDTHS="2 2:3"}{print $1,$2}' a.txt

3.行列转换
name age
alice 21
ryan 30

结果:
name alice ryan
age 21 30

name alice ryan
第一行数据来源为第一列,而且跨行,我们需要利用数组保存起来

age 21 30
awk '
    {
      for(i=1;i<=NF;i++){
          if(!(i in arr)) {
          	arr[i]=$i
          }else {
          	arr[i]=arr[i]" "$i
          }
      }
    }
    END{
        for(i=1;i<=NF;i++){
            print arr[i]
        }
    }
' a.txt
数据:
74683 1001
74683 1002
74683 1011
74684 1000
74684 1001
74684 1002
74685 1001
74685 1011
74686 1000
....
100085 1000
100085 1001

希望得到:
74683 1001 1002 1011
74684 1000 1001 1002

代码:
{  
  arr[$1] = arr[$1]" "$2
}​
END{
  for(i in arr){
      printf "%s %s\n",i,arr[i]
  }
}

筛选给定时间范围内的日志实例

1.精确到秒的日志1
实现的是将 2019-11-10T03:42:40+08:00 格式的字符串转换成 epoch 值,然后和 which_time 比较大小即可筛选出精确到秒的日志。

BEGIN{
    #要筛选什么时间的日志,将其时间构建成epoch值
    which_time = mktime("2019111083 42 40")
}
 
 
{
    #取出日志中的日期时间字符串部分
    match ($O, "^,*\l[(.*)ll].*" , arr)
 
    #将日期时间字符串转换为epoch值
    tmp_time = strptime1(arr[1])
 
    #通过比较epoch值来比较时间大小
    if(tmp_time > which_time){print}}
}
 
    #构建的时间字符串格式为:"2019-11-10T83:42:40+08:80"
    function strptime1 (str,arr ,Y,M,D, H, m, S) {
    dt_str = gensub( "[/:+]"," ", "g",str)
    #10 Nov 2019 23 53 4408 00
    split(dt_str,arr,"[0-9]{1,4}")
 
    Y=arr[1]
    M=arr[2]
    D=arr[3]
    H=arr[4]
    m=arr[5]
    S=arr[6]
 
    #通过mktime构建字符串
    return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}

2.实现的是将10/Nov/2019:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

BEGIN{
  # 要筛选什么时间的日志,将其时间构建成epoch值
  which_time = mktime("2019 11 10 03 42 40")
}
 
{
  # 取出日志中的日期时间字符串部分
  match($0,"^.*\\[(.*)\\].*",arr)
  
  # 将日期时间字符串转换为epoch值
  tmp_time = strptime2(arr[1])
  
  # 通过比较epoch值来比较时间大小
  if(tmp_time > which_time){
    print 
  }
}
 
# 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"
function strptime2(str   ,dt_str,arr,Y,M,D,H,m,S) {
  dt_str = gensub("[/:+]"," ","g",str)
  # dt_sr = "10 Nov 2019 23 53 44 08 00"
  split(dt_str,arr," ")
  Y=arr[3]
  M=mon_map(arr[2])
  D=arr[1]
  H=arr[4]
  m=arr[5]
  S=arr[6]
  return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}
 
function mon_map(str   ,mons){
  mons["Jan"]=1
  mons["Feb"]=2
  mons["Mar"]=3
  mons["Apr"]=4
  mons["May"]=5
  mons["Jun"]=6
  mons["Jul"]=7
  mons["Aug"]=8
  mons["Sep"]=9
  mons["Oct"]=10
  mons["Nov"]=11
  mons["Dec"]=12
  return mons[str]
}

你可能感兴趣的:(服务器,linux,mysql)