zoukankan      html  css  js  c++  java
  • SHELL脚本扩展

    使用SED命令

    sed称为流编辑器,命令格式如下:

    sed option script file
    -e script   #指定多个命令
    -f script_file   #指定命令文件
    -n  #不需要为每个命令产生输出

    1)s替换命令:使用第二个文本字符串替换第一个两个斜杆之间指定的文本

    sed 's/dog/cat/' data1  #在data1之中使用cat替换dog

    sed -e 's/dog/cat/; s/brown/green/' data1  #在data1之中执行两个替换,注意两个s命令之间需要使用分号隔开

    复制代码
    #s命令默认只能替换每行首次匹配字符
    #可以使用替换标记来进行灵活设置
    s/pattern/replacement/flags
    #flags取值如下:
    数字:表示替换第几个匹配到得关键字
    g:表示替换所有匹配的字符串(不仅仅每行第一个)
    p:打印原始行的字符串
    w:将替换的结果写入到文件之中
    复制代码
    sed 's/dog/cat/2' data1  #替换每行的第二次匹配的模式
    sed 's/dog/cat/g' data1  #替换每行所有匹配的模式
    sed -n 's/dog/cat/p' data1  #-n选项禁止编辑器输出,p选项输出修改的行,二者结合结果就是只输出修改后的行
    sed 's/dog/cat/w test' data1   #将输出写入到文件test之中

     字符串标记!在两个!之间表示一个字符串,该符号可用于替换斜杆/, 

    sed 's!/bin/bash!/bin/csh!' data1   #使用/bin/csh替换/bin/bash

    sed 's!dog!cat!' data1  #使用cat替换dog

    2)使用地址

    [address]command

    或者多命令着方式

    [address]{

      command

      command .....

    }

    sed '2s/dog/cat/' data1     #修改第二行
    sed '2,3s/dog/cat/' data1  #修改2,3行 
    sed '2,$s/dog/cat/'  data1 #修改2~末尾行

    3)使用文本模式筛选器

    /pattern/command   #只有匹配pattern的行才会执行command命令

    4)其他命令

    复制代码
    d:删除行
    i:插入命令
    a: 附加命令
    y:变换命令
    =:打印行号
    l: 列出行
    w: 写文件
    r: 读文件
    复制代码

    [address]y/inchars/outchars/ #将inchars中得字符与outchars一一对应进行变换
    sed 'y/123/789/' data1 #将1-7,2-8,3-9方式进行替换

     使用正则表达式
     

    1、^字符放在模式的开头:表示开头匹配(放在其他位置没有作用)

      sed -n '/^Two/p' data3  #以Two开头的模式匹配

    2、$字符放在模式的结尾:表示结尾匹配(放在其他位置没有作用)

      sed -n '/text$/p' data3  #以text结尾的模式匹配

      sed -n '/^One line of test text$/p' data3  #联合匹配

      sed '/^$/d' data3   #使用^$匹配空行,并且使用d命令删除空行

     3、.字符,匹配除换行符外的单个字符,并且必须要有一个字符

      sed -n '/dog..5/p' data1  #匹配dog.[]5 其中一个点使用了转义

    4、字符类

      [abc]  #匹配abc中得任意一个字符

      [0-9]  #匹配范围 0~9 之间的任意一个字符

      [a-z]   #匹配字母

      sed -n '/^[0-9][0-9][0-9]$/p'  #匹配3位数值型,注意^$的使用

    复制代码
    特殊字符类
    [[:alpha:]]  #匹配字母(大小写)
    [[:alnum:]]  #任意字母或者数值
    [[:blank:]]  #空格或者制表符
    [[:digit:]]    #数值
    [[:lower:]]  #小写字母
    [[:upper:]]  #大写字母
    [[:print:]]   #可打印字符
    [[:punct:]]   #标点符号
    [[:space:]]  #空白字符
    复制代码

    5、星号:在某个字符后使用,表示该字符必须在匹配的文本中不出现或者出现多次。联合使用点号 .* 表示匹配任意字符一次或者多次。

    6、问号:前面的字符不出现或者只出现一次

      echo "bet" | gawk '/b[ae]?t/{print $0}'   #问号与字符类联合使用表示字符类不出现或者只出现一次

    7、加号:表示之前的模式出现一次或者多次,至少一次

    8、大括号:表示之前的模式出现指定次数

      m: 表示出现m此

      m,n: 表示出现m~n次之间  

      echo "bet" | gawk '/b[ae]{1,2}t/{print $0}'  #表示[ae]出现1~2次

     9、管道:表示连接的多个模式只要一个匹配即可通过

      echo "The cat is asleep" | gawk '/cat|dog/{print $0}'   #匹配cat或者dog

     10、使用括号将表达式分组,分组后就可以将其作为一个模式,与星号、问号等联合使用

      echo "Saturday" | gawk '/Sat(urday){1}/{print $0}'

     使用gawk
     

    1、命令格式

    gawk options program file
    -F fs  #指定数据字段分隔符
    -f script_file #指定脚本命令文件
    -v var=value  #定义变量与默认值
    #其中的program命令以大括号方式给出

    2、print命令

    echo "" | gawk '{print "Hello"}'

    3、数据字段

      gawk命令自动将每行文本使用分隔符进行分割,然后可以引用这些字段

      $0  整行文本

      $1  第一个字段,依次类推

    echo "My name is Rich" | gawk '{$4="Zcs"; print $0}'
    #将第四个字段修改成zcs,然后打印,注意多个命令之间使用分号分隔。
    
    gawk -F: script2 /etc/passwd  #使用F指定分隔符
    #也可以在脚本内部使用FS变量指定分隔符

    4、BEGIN与END命令模块

      分别用于指定在执行命令脚本前执行与之后执行。

    echo "My name is Rich" | gawk 'BEGIN {print "Hello World"} {$4="Zcs"; print $0} END {print "END"}'   #分别指定了BEGIN与END命令块

    5、内置变量

    复制代码
    FIELDWIDTHS:采用固定长度作为分割字段依据,此时FS无效
    FS:输入字段分割符号
    OFS:输出字段分割符号(在print中使用)
    RS,ORS :用于设置输入行的分割方式(FS为行内部,RS为行之间)
    gawk 'BEGIN{FS=" ";OFS="-"} {print $1,$2,$3,$4}' data1 #设置了OFS为横线
    gawk 'BEGIN{FS=" ";OFS="-";FIELDWIDTHS="5 5 5 5"} {print $1,$2,$3,$4}' data1  #设置了FIELDWIDTHS后,FS无效,并且使用其作为分割字段依据
    
    ARGC,ARGV:分别表示gawk运行时参数个数,与参数数组,从0开始索引,该参数是调用gawk时的参数,索引位置0表示为gawk,命令部分不算,如下:
    gawk 'BEGIN{print ARGC,ARGV[1]}' data1  #2 data1
    
    ENVIRON以关联数组方式检索环境变量  
    ENVIRON["HOME"]
    
    NF:表示每行分割出来的最后一个字段索引,使用$NF来引用最后一个字段
    gawk 'BEGIN{FS=":";OFS=":"} {print $1,$NF}' /etc/passwd
    
    FNR、NR:前者表示当前输入文件已处理记录数,处理完一个输入文件时该值被重置,NR表示当前总的处理记录数
    gawk 'BEGIN{FS=" "} {print $1,"FNR="FNR,"NR="NR}' data1 data1
    复制代码

    6、使用自定义变量

      gawk允许使用-v在命令行中设置自定义变量,另外在BEGIN模块中也可以自定义变量,格式都为var=value

      特别需要注意的是,在gawk内部引用不变量不需要加美元符号。

    gawk -v val=2 '{print val}' data1
    注意:在gawk之中变量的引用不需要使用$符号,只在引用被分割的字段时需要使用。

    7、使用数组

      gawk内部数组采用关联数组方式,类似map,需要使用关键字来引用。

      可以使用for循环遍历(但是不保证每次遍历以同样顺序),可以使用delete来输出项。

    复制代码
    gawk 'BEGIN{
        var["a"]=1
        var["b"]=2
        for(test in var)  #使用for循环遍历数组
        {
            print "Index:",test," - value:",var[test]
        }
        delete var["b"]  #输出关键字b
        print "----"
        for(test in var)
        {
            print "Index:",test," - value:",var[test]
        }
    }'
    
    #output
    Index: a  - value: 1
    Index: b  - value: 2
    ----
    Index: a  - value: 1
    复制代码

    8、模式匹配

      1)在大括号(命令)前使用双斜线作为正则表达式来匹配

    gawk '/dog/{print $0}' data1

      2)使用模式操作符~加上正则表达式来进行匹配

    gawk '$2 ~ /^quick/{print $0}' data1  #表示第二个字段需要匹配/^quick/

      3)使用数学表达式匹配

    gawk -F: '$4 == 0{print $1}' /etc/passwd  #精确匹配第四个字段等于零

    9、结构化语句

      1)if语句

    gawk '{if ($10 > 1) print $0}' data1
    gawk '{if ($10 > 1) print $0; else print "hahahah"}' data1
    #若if语句中有多条命令需要使用大括号包围住。

      2)循环语句

    复制代码
    #如下脚本统计输入文件中以空格分隔的多个数值的和
    
    inputFile=$1
    gawk 'BEGIN{total=0;lineTotal=0} {
    i=1
    lineTotal=0
    print $0,NF
    while (i <= NF) {   #使用NF内部变量来获取每行分隔的字段数
        lineTotal += $i
        i = i+1
    }
    print $0,"total:",lineTotal
    total = total + lineTotal
    }
    END{print "total is ",total}' $inputFile
    
    #同时while语句还支持break、continue关键字
    do
    {
        statements
    } while (condition)
    与while在条件判断上有区别,循环中得语句至少运行一次
    
    for ( i=1; i<10; i++)
    {
        statements
    }
    复制代码

    10、格式化输出 printf 命令

    11、gawk还提供了数学函数、字符串函数、时间计算函数,还可以自定义函数

     
     
     
     
  • 相关阅读:
    解决docker-compose: command not found
    idea 包存在提示不存在
    使用haproxy负载均衡
    docker使用阿里云仓库上传与下拉images
    docker使用官方仓库上传与下拉images
    WeaveScope-容器监控
    matlab打开
    硬盘测试
    matlab quiver()画箭头的函数
    SDK 和 API 的区别是什么?
  • 原文地址:https://www.cnblogs.com/chang290/p/3586362.html
Copyright © 2011-2022 走看看