• sed 以及 awk用法


      

    sed 格式
    sed[options] "script" FILE....

    选项:
    -n:静默模式,不输出模式空间内的内容;默认打印空间模式的内容
    -r:扩展的正则表达式
    -f 文件:指定sed脚本文件
    -e 'script' -e 'script' :指定多个编辑指令
    -i : 直接编辑原文件


    编辑命令:
    d:删除
    p: 打印
    i ext:在被指定到的行前面插入文本
    a ext:在被指定的行的下面插入文本
    :换行
    r /path/file.txt:在指定位置把另外一个文件的内容插入
    w /path/file.txt:将符合条件的所有行保存至指定文件中
    =:显示符号条件的行的行号
    s///:查找条件可以使用模式,但是要替换的内容不行

    sed '地址定界s@查找条件@替换文件@'
    修饰符:
    g:global,全局替换
    i:ignore-case,不区分字符大小写

    地址定界:自定义的起始行到结束行
    startline,endline
    1,3
    /pat1/,/pat2/
    /pattern/

    用法:sed [options] 'addr1[,addr2]编辑命令' FILE...
    sed [options] "addr1[,addr2]编辑命令" FILE...

    用法

    1. 删除 /etc/puppet/puppet.conf 1到13行的数据
    [root@k8s1 ~]# sed '1,13d' /etc/puppet/puppet.conf

    2. 删除以空格或者tab的集合开头的行
    [root@k8s1 ~]# sed '/^[[:space:]]/d' /etc/puppet/puppet.conf 

    3.删除空行
    [root@k8s1 ~]# sed '/^[[:space:]]*$/d' /etc/puppet/puppet.conf

    4.删除fstab中以/ 开头的行。
    [root@k8s1 ~]# sed '/^//d' /etc/fstab

    5.删除第2行到第一次出现 / 的行,结束是在/ 行后
    [root@k8s1 ~]# sed '2,/^//d' /etc/fstab

    6.删除以 # 开始到第一次出现 / 的行,结束是在/ 行后
    [root@k8s1 ~]# sed '/^#/,/^//d' /etc/fstab
    7.显示打印以 # 开始到第一次出现 / 的行,结束是在/ 行后
    [root@k8s1 ~]# sed -n '/^#/,/^//p' /etc/fstab
    8.在空行前添加 11111111111111 
    [root@k8s1 ~]# sed '/^$/i 111111' /etc/fstab
    [root@k8s1 ~]# sed '/^[[:space:]]*$/i 111111' /etc/fstab
    9.在空行后添加 11111111111111 
    [root@k8s1 ~]# sed '/^$/a 111111' /etc/fstab
    [root@k8s1 ~]# sed '/^[[:space:]]*$/a 111111' /etc/fstab

    10.在大写字母后添加2行
    [root@k8s1 ~]# sed '/^[[:upper:]]/a aaaaaaaaaaa bbbbbbbbb' /etc/issue

    11. 在一个大写字母行后,把另一个文件内容追加进来。
    [root@k8s1 ~]# sed '/sda2/r /etc/issue' /etc/fstab

    12. 将fstab 中包含 / 的保存在/tmp/file.txt中
    sed '///w /tmp/file.txt' /etc/fstab

    13.显示匹配的行号
    [root@k8s1 ~]# sed '///=' /etc/fstab

    14. 把 /etc/issue内容 添加到fstab 第2行后
    [root@k8s1 ~]# sed  '2r /etc/issue' /etc/fstab

    list.txt 文件内容如下:

      docker:x:996:993:Docker User:/var/lib/docker:/sbin/nologin
      etcd:x:995:992:etcd user:/var/lib/etcd:/sbin/nologin
      puppet:x:52:52:Puppet:/var/lib/puppet:/sbin/nologin
      centos:x:2000:2000::/home/centos:/bin/bash
      nginx:x:990:9909:Nginx web server:/var/lib/nginx:/sbin/nologin

     15.删除一行中出现相同docker的行
     [root@k8s1 ~]# sed '/(d.*r).*1/d' list

      16.删除一行中出现相同字符的行
     [root@k8s1 ~]# sed '/(*.).*1/d' list

    17.替换第二个docker为Docker
    [root@k8s1 ~]# sed  '/(d.*r).*1/s@dockeri@Dockeri@'  list

    18.替换 /etc/inittab 中 id:3:initdefault 变成数字5
    [root@python tmp]# sed '/id:/s@[0-9]@5@' /etc/inittab

    19.替换/etc/inittab 中 以#开头和后面有空格的行
    [root@python tmp]# sed '/^#/s@^#[[:space:]]{0,1}@@g' inittab

    20.删除/etc/inittab 中所有开头是空白的行
    sed 's@^[[:space:]]{1,}@@g'  /etc/inittab


    awk命令:
    awk:报告生成工具
    把文件中读取带的每一行的每个字段分别进行格式化,而后进行显示:

    支持使用变量、条件判断、循环、数组

    选项:
      -F:切割符
      $0:整行
      $1,$2.....:位置参数


    用法格式:
    awk [options] 'script' FILE...
    awk [options] '/pattern/{action}' FILE...

    action: print $1,$2

    [root@k8s1 ~]# awk -F":" '{print $1}'  /etc/passwd

    模式:
      地址定界:/pat1/,/pat2/ 一个范围        
      /pattern/ 被匹配到的行


      experssion 表达式   $3 > 2000
      >,>=,<,<=,==,!=,~(模式匹配)


      BEGIN:在遍历操作开始之前执行一次:   awk 'BEGIN{print "name"}{print $1,$2}'
      END:在遍历操作结束之后,命令退出之前退出一次。    awk 'BEGIN{print "name"}{print $1,$2}END{print “----------”}'

    awk的常用四种分隔符:
    输入:
      行分隔符
      字段分隔符
    输出:
      行分隔符
      字段分隔符


    awk内置变量之数据变量:
    NR: The number of input records,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数;
    NF:Number of Field,当前记录的field个数;
    FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数;
    ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt;
    ARGC: awk命令的参数的个数;
    FILENAME: awk命令所处理的文件的名称;在命令中获取当前文件名
    ENVIRON:当前shell环境变量及其值的关联数组;

    [root@k8s1 ~]# awk -F":" '/centos/{print $0}'  /etc/passwd
    centos:x:
    2000:2000::/home/centos:/bin/bash

     [root@k8s1 ~]# awk -F":" '/12/{print $0}' /etc/passwd
     mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
     games:x:12:100:games:/usr/games:/sbin/nologin

     [root@k8s1 ~]# awk -F":" '$3>2000 {print $0}' /etc/passwd
     suse:x:3000:3000::/home/suse:/bin/bash

    [root@k8s1 ~]# awk 'BEGIN{print "name:-------"}{print $1} END{print "-----------------"}' /etc/passwd
    name:-------

    ......

    ----------

    显示最后一列

    [root@k8s1 ~]# awk -F":" '{print $NF}' /etc/passwd
    /bin/bash
    /sbin/nologin
    /sbin/nologin

    输入按照:号切割,输出按照+号显示

    [root@k8s1 ~]# awk 'BEGIN{FS=":";OFS="+"}{print $1,$7}' /etc/passwd

    root+/bin/bash

    使用NR 显示总行数

    [root@k8s1 ~]# awk '{print NR,$0}' /etc/passwd  /etc/fstab

    使用FNR 对每个文件计数

    [root@k8s1 ~]# awk '{print FNR,$0}' /etc/passwd  /etc/fstab

    ARGV[0] 等于awk,ARGV[1]等于/etc/passwd,但是会循环显示 /etc/passwd

    [root@k8s1 ~]# awk -F ":" '{print ARGV[0]}' /etc/passwd

    可以使用BEGIN,在循环前执行

    [root@k8s1 ~]# awk 'BEGIN{print ARGV[0]}'

    [root@k8s1 ~]# awk -F":" '{print $1“ is a user in ”ARGV[1]}' /etc/passwd

    FILENAME: awk命令所处理的文件的名称;在命令中获取当前文件名

    [root@k8s1 ~]# awk '{print $0" in "FILENAME}' /etc/passwd

    使用-v 自定义变量,或者直接在BEGIN中定义

    [root@k8s1 ~]# awk -v num1=30 -v num2=30  'BEGIN{print num1+num2}'

    [root@k8s1 ~]# awk 'BEGIN{num1=20;num2=30; print num1+num2}'

    条件表达式 if 

    print 的区别,一个对整个行操作,一个在操作行之前操作

    [root@k8s1 ~]# awk 'BEGIN{num1=231;num2=500;num1>num2?max=num1:max=num2;print max}'
    500

    [root@k8s1 ~]# awk 'BEGIN{num1=30;num2=55;num1>num2?max=num1:max=num2} {print max}' /etc/passwd
     

    printf

    printf命令的使用格式:
    printf format, item1, item2, ...

    要点:
    1、其与print命令的最大不同是,printf需要指定format;
    2、format用于指定后面的每个item的输出格式;
    3、printf语句不会自动打印换行符;

    format格式的指示符都以%开头,后跟一个字符;如下:
    %c: 显示字符的ASCII码;
    %d, %i:十进制整数;
    %e, %E:科学计数法显示数值;
    %f: 显示浮点数;
    %g, %G: 以科学计数法的格式或浮点数的格式显示数值;
    %s: 显示字符串;
    %u: 无符号整数;
    %%: 显示%自身;

    修饰符:
    N: 显示宽度;
    -: 左对齐;
    +:显示数值符号;

    例子:

    [root@k8s1 ~]# awk -F":" '{printf "%-20s %s
    ",$1,$NF}' /etc/passwd
      

    [root@k8s1 ~]# awk 'BEGIN{sum=55;printf "%d ",sum}'
    55


    常见的模式类型:


    1、Regexp: 正则表达式,格式为/regular expression/
    2、expresssion: 表达式,其值非0或为非空字符时满足条件,如:$1 ~ /foo/ 或 $1 == "magedu",用运算符~(匹配)和!~(不匹配)。
    3、Ranges: 指定的匹配范围,格式为pat1,pat2
    4、BEGIN/END:特殊模式,仅在awk命令执行前运行一次或结束前运行一次
    5、Empty(空模式):匹配任意输入行;


    /正则表达式/:使用通配符的扩展集。

    关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>%1选择第二个字段比第一个字段长的行。

    模式匹配表达式:

    模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。

    BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。

    END:让用户在最后一条输入记录被读取之后发生的动作。

    控制语句:
    1 if-else
    语法:awk '{if (condition) {then-body} else {[ else-body ]}}'

    [root@k8s1 ~]# awk '{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}' /etc/passwd
    [root@k8s1 ~]# awk -F":" '{if ($3==0) {printf "%-18s $s
    ",$1,"is administrator"} else {printf "%-18s %s
    ",$1,"is comm user"}}' /etc/passwd
      

      统计匹配的行,sum++ 就是循环一次,自身加1

    [root@k8s1 ~]# awk -F: -v sum=0 '{if ($3>500) {sum++}} END{print sum}'  /etc/passwd
    [root@k8s1 ~]# awk -F":" 'BEGIN{sum=0} {if($4="192.168.2.1") {sum++}} END{print sum}' fengjian

    while
    语法:awk  '{i=1; while (i<5) {print $i;i++}}'  file

    [root@k8s1 ~]# awk -F":" '{i=1; while(i<NF) {printf "%s:",$i;i++} ;printf "
    "}' /etc/passwd
     
    [root@k8s1 ~]# awk -F":" '{i=1; while(i<NF) {if($i==3000) {print $i};i++}}' /etc/passwd
      
    
    

    for
    语法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...}

    [root@k8s1 ~]# awk -F":" '{for(i=1;i<=NF;i++){printf "%s:",$i};printf "
    "}' /etc/passwd

     

    [root@k8s1 ~]# awk -F":" '{for(i=1;i<=NF;i+=2){printf "%s:",$i};printf " "}' /etc/passwd

      

    
    

    for循环还可以用来遍历数组元素:
    语法: for (i in array) {statement1, statement2, ...}
    awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i ",A,BASH[A]}}' /etc/passwd

    array[index-expression]

    index-expression可以使用任意字符串;需要注意的是,如果某数据组元素事先不存在,那么在引用其时,awk会自动创建此元素并初始化为空串;因此,要判断某数据组中是否存在某元素,需要使用index in array的方式。

    要遍历数组中的每一个元素,需要使用如下的特殊结构:
    for (var in array) { statement1, ... }
    其中,var用于引用数组下标,而不是元素值;

    例子:
    netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
    每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引;

    awk '{counts[$1]++}; END {for(url in counts) print counts[url], url}' /var/log/httpd/access_log
    用法与上一个例子相同,用于统计某日志文件中IP地的访问量

    从关系数组中删除数组索引需要使用delete命令。使用格式为:

    delete array[index]

    [root@haproxy1 ~]# netstat -an | awk '/^tcp/{state[$NF]++} END{for(A in state) {print A,state[A]}}'

    统计非空白行访问IP的数量

    [root@tracker1 logs]# awk '!/^!/{ACCESS[$1]++} END{for(a in ACCESS) {print a,ACCESS[a]}}' access.log

    统计访问的路径

    [root@S1PW003 logs]# awk '/GET/{res[$7]++} END{for(i in res) {print i,res[i]}}' access.log

    统计varnish状态码 

    [root@haproxy1 logs]# awk '/varnish/{code[$11]++} END{for(i in code) {print i,code[i]}}' haproxy_http.log

      

    显示为基数的行/etc/passwd,使用next

    [root@k8s1 ~]# awk -F":" '{if($3%2==0) {next} else {print $1,$3}}' /etc/passwd

     统计当前系统上每个客户端IP的连接中处于TIME_WAIT的连接状态的个数;

    [root@xinyixy_pc_006 ~]# netstat -an | awk '/TIME_WAIT/{laststr[$NF]++} END{for(i in laststr) {print i,laststr[i]}}'

    统计ps aux命令执行时,当前系统上各用户的进程的个数;

    root@xinyixy_pc_006 ~]# ps aux | awk '{state[$8]++}END{for(i in state) {printf "%-15s %s ",i,state[i]}}'

    awk的内置函数

    awk '{split(分割的字段, 数组名称 ,分割符)'}


    功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从1开始的序列;

    # netstat -ant | awk '/:80>/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50

    # netstat -tan | awk '/:80>/{split($5,clients,":");ip[clients[4]]++}END{for(a in ip) print ip[a],a}' | sort -rn | head -50

    # df -lh | awk '!/^File/{split($5,percent,"%");if(percent[1]>=20){print $1}}'

    [root@xinyixy_ha_001 ~]# netstat -anpt | awk '{split($7,program,"/");res[program[2]]++} END{for(i in res) {print res[i],i}}'

    length([string])
    功能:返回string字符串中字符的个数;


    substr(string, start [, length])
    功能:取string字符串中的子串,从start开始,取length个;start从1开始计数;

    system(command)
    功能:执行系统command并将结果返回至awk命令

    systime()
    功能:取系统当前时间

    tolower(s)
    功能:将s中的所有字母转为小写

    toupper(s)
    功能:将s中的所有字母转为大写

  • 相关阅读:
    洛谷 P1781 宇宙总统
    洛谷 P2524 Uim的情人节礼物·其之弐(康拓展开)
    洛谷 P1123 取数游戏
    洛谷 P4147 玉蟾宫 & P1169 [ZJOI2007]棋盘制作(求最大子矩阵)
    洛谷 P1387 最大正方形 & P2701 [USACO5.3]巨大的牛棚Big Barn (求最大子正方形)
    洛谷 P1464 Function
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes
    洛谷 P1160 队列安排
    洛谷 P1451 求细胞数量
    洛谷 P1914 小书童——密码
  • 原文地址:https://www.cnblogs.com/fengjian2016/p/6835054.html
Copyright © 2020-2023  润新知