zoukankan      html  css  js  c++  java
  • 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中的所有字母转为大写

  • 相关阅读:
    LeetCode 623. Add One Row to Tree
    LeetCode 894. All Possible Full Binary Trees
    LeetCode 988. Smallest String Starting From Leaf
    LeetCode 979. Distribute Coins in Binary Tree
    LeetCode 814. Binary Tree Pruning
    LeetCode 951. Flip Equivalent Binary Trees
    LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List
    LeetCode 889. Construct Binary Tree from Preorder and Postorder Traversal
    LeetCode 687. Longest Univalue Path
    LeetCode 428. Serialize and Deserialize N-ary Tree
  • 原文地址:https://www.cnblogs.com/fengjian2016/p/6835054.html
Copyright © 2011-2022 走看看