sed命令和awk命令详解

vim和sed、awk之间的区别:

    vim命令是交互式的,sed和awk是非交互式的。比如vim需要i来插入,需要wq来保存退出

    vim命令使文件操作模式,sed和awk是行操作模式。

sed命令:

1.sed作用

    sed一般用于对文本内容做替换(不一定非用/分割,任意字符都可以):

        如sed '/usr1/s/usr1/u1/' /etc/passwd

2.sed的模式空间

    sed的基本工作方式为:

        将文件的每一行读取到内存(模式空间)

        使用sed的每个脚本匹配行,对该行进行操作

        处理完成后输出该行(同echo输出),没有匹配到就原样输出

3.sed的替换命令s:

    -e:使用多个指令,每个指令前都加-e

    -i:替换完成后,将得到的内容写回文件中,替换原来的内容

    sed 's/old/new/' filename

    示例:

    sed -e 's/a/aa/' -e 's/aa/bb/' afile bfile:

        将文件中每一行的首个a变成b,再变成bb,如原文件中内容为a a a,则输出为bb a a

        简化写法:sed 's/a/aa/;s/aa/bb/' afile bfile

    sed -i 's/a/aa/' 's/aa/bb/' afile bfile:

        将文件中每一行的首个a变成b,再变成bb,如原文件中内容为a a a,不输出,将原文

        件中的内容替换为bb a a

    sed 's/...//' afile:

        将文件中每一行前三个字符替换去掉,放心试,没有加-i不会替换原文件的

    sed 's/s*bin//' afile:

        去掉第一个bin或sbin,s*表示0-n个s

    sed 's/^a/b/' afile:

        将每一行开头的a改为b

4.拓展元字符:

    -r:可使用拓展正则表达式,使用拓展元字符必须使用-r

    示例:

        sed -r 's/ab+/!/' afile:

            将每一行中第一个ab+改为!,b+有1-n个。+为扩展元字符,必须使用-r

        sed -r 's/a|b/!/' afile:

            将每一行第一个a或b改为!

        sed -r 's/(aa)|(bb)/!/' afile:

            将每一行第一个aa或bb改为!,不能是sed -r 's/aa|bb/!/',因为识别不了,会被当成

            sed -r 's/a a|b b/!/',意思为将a a或b b改为!

        sed -r 's/.*(login)/\1 \1/' /etc/passwd:

            ()中的内容为一组,\1表示第一组,结果如下:

            root:x:0:0:root:/root:/bin/bash

            login login

            login login

            login login

            login login

            sync:x:5:0:sync:/sbin:/bin/sync

5.替换命令加强版:

    全局替换:

        s/old/new/g,全部替换,并不是只替换第一个,如:    

            sed 's/a/b/g' afile: 将每一行中所有的a替换成b

        s/old/new/2,将每一行第二次出现old替换为new,如:    

            sed 's/a/b/2' afile: 将每一行中第二次出现的a替换成b

    s/old/new/p afile:

        没有匹配到old的行不输出

    s/old/new/w afile /usr/local/a.txt:

        将替换成功的行写入到指定文件中

    寻址:

        增加寻址后,只对寻址后的行加载然后匹配。

        /正则表达式/s/old/new/g

        行号s/old/new/g

            行号可以是具体的行,也可以是最后一行,使用$符号

        可以使用两种寻址符号,也可以行号和正则混合使用

        示例:

            sed '/^a/s/a/b/' afile

            sed '1s/a/b/' afile

        匹配多个命令:/regx/{s/old/new/;s/old/new}

    脚本文件:

        sed -f sedscript filename,将sed命令写到脚本文件中,直接使用

6.sed其他命令

    删除:sed [行号或正则]d

        sed '/ab/d' afile, 删除行中有ab的行,只是在模式空间里的输出变化,原文件不变

    追加、插入、更改:

        sed '/ab/i hello' afile,有ab的上一行插入hello

        sed '/ab/a hello' afile,有ab的下一行插入hello

        sed '/ab/c hello' afile,有ab的行内容替换为hello

    打印命令:p ,sed -n '/ab/p' afile 只打印有ab的行

    打印行号命令:=

    下一行:-n,逐行读取,默认是全部读取

        打印行号:sed -n = afile

    读文件和写文件:

        sed '/ab/r bfile' afile, 将afile中有ab的行内容与bfile合并

        sed '/ab/w bfile' afile, 将afile中有ab的行写到bfile

    退出命令:q

        只打印1-10行:

        sed -n '10q' afile (性能更加,只读取前10行)

        sed -n '1,10p' afile

7.sed的多行模式

    为什么要有多行模式:

        配置文件可能有多行情况,用简单替换无法替换配置文件

    N:

        将下一行加入到模式空间

        sed 'N;s/hel\nlo/!!!/' a.text 或 sed 'N;s/.*/!!!/' a.text

        a.text内容如下:

            hel

            lo

    D:

        删除模式空间中的第一个自读到第一个换行符

    P:

        打印模式空间中的第一个字符到第一个换行符

8.保持空间

    保持孔家你也是多行的一种操作方式

    将内容暂存在保存空间,便于做多行处理

    流程: 文本文件 -> 模式空间 -> 保持空间

    h和H将模式空间内容放到保持空间,小写是覆盖,大写是追加

    g和G将保持空间内容放到模式空间,小写是覆盖,大写是追加

    x交换保持空间和模式空间

    示例:

        将文件内容倒序输出: sed -n '1h;1!G;$!x;$p' file

        过程:拿纸推导吧

awk命令:

1.awk作用

    awk一般用于文本内容进行统计、按需要的格式进行输出,例如:

        完整格式:'BEGIN{...}{}END{...}'

        示例:

        cut写法:cut -d : -f 1 /etc/passwd

        awk写法:awk -F: '/wd$/{print $1}' /etc/passwd

2.awk的字段和使用

    每行成为awk的记录

    使用空格、制表符分隔开的单词称作字段

    字段引用:

        awk中使用$1 $2 ... $n 表示每一个字段, $0为全部,与shell中$0是文件名不同

        NF表示总个数

    

    字段分割:

        awk可以使用-F选项改变字段分隔符(可以用正则):

            awk -F',' '{print $0}' afile

    行匹配:

        awk脚本开头可以用/regx/匹配行:

            awk '/^a/{print $0}' afile:打印a开头的行

        

    示例,有如下文件,打印文件中以menu开头的行中操作系统类型,并显示序号:

            menu 'windows'

            1234

            menu 'linux'

            abc

            menu 'mac'

        答案: awk -F"'" '/^menu/{print x++,$2}' afile

3.判断和循环

    if语句:

        if(表达式){语句}else{语句}

        示例:

            echo 1 2 3 | awk '{if($2>$3){print 1}else{print 0}}'

    while循环:

        while(表达式){语句}

    do while循环:

        do{语句}while(表达式)

    for循环:

        打印0-9:

            echo : | awk '{for(i=0;i<10;i++){print i}}'

        打印每个参数:

            echo 1 2 3 | awk '{for(i=1;i<=NF;i++){print $i}}'

        打印参数的总和:

            echo 1 2 3 | awk '{sum=0;for(i=1;i<=NF;i++){sum+=$i};print sum}'

    break和continue和其他语言相同

4.awk数组

    数组的定义:

        数组名称[下标]=值

            下标可以用数字或字符串,实际上数字也会被存为字符串

    数组的遍历

        for(变量 in 数组名称)

    数组的删除

        delete 数组名称

        delete 数组名称[下标]    

    示例:

        echo 1 2 3 | awk '{for(i=1;i<=NF;i++){arr[i]=$i}}END{for(ele in arr) 

        print ele, arr[ele]}'

    命令行参数数组:

        ARGC 参数个数

        ARGV 参数数组,ARGV[0] 表示命令名称,这里是awk

        示例:

            创建arg.awk文件,内容:BEGIN{for(i=0;i

            awk -f arg.awk 11 22 33,结果:

                awk

                11

                22

                33

5.awk函数

    算数函数:

        sin() cos()

        int()

        rand():获取随机数[0,1),重复执行是一样的值

        srand()重新获取种子,每次rand()前先使用srand();

    字符串函数:

        以下函数可以用man awk | less,搜索看其含义

        gsub(r,s,t)

        index(s,t)

        length(s)

        match(s,r)

        split(s,a,sep)

        sub(r,s,t)

        substr(s,p,n)

    自定义函数:

        function 函数名(参数){

            语句

            return 返回值

        }

        需要定义在BEGIN之前,示例:

        awk 'function a(num){ return num } BEGIN{print a(0)}'

你可能感兴趣的:(运维,awk,shell)