本文作者:心月

linux文本处理三剑客(grep、sed、awk)命令选项整理

心月IT博客 06-13
linux文本处理三剑客(grep、sed、awk)命令选项整理摘要:Linux中最重要的三个命令:awk,sed,grep,在业界被称为“三剑客”。

1、grep和egrep(过滤器)

    grep:

        grep [选项][匹配条件][file1 file2...] (在文件中查找)

        command|grep[选项][匹配条件]


        常用选项:

    -v:不显示匹配行信息
    -i:搜索时忽略大小写
    -n:显示行号
    -r:递归搜索
    -E:支持扩展正则表达式
    -F:不按正则表达式匹配,按照字符串字面意思匹配

        不常用 选项:    

    -c:只显示匹配行总数    
    -w:匹配整词
    -x:匹配整行
    -l:只显示文件名,不显示内容
    -s:不显示错误信息

        使用示例:

          grep "bin" shell/test1.sh     //在文件test1.sh中查找bin内容
          grep -E "bin|BIN" shell/test1.sh     //查找bin或BIN

    

    egrep:

        grep默认不支持扩展正则表达式,值支持基础正则表达式

        使用grep -E可以支持扩展表达式

        使用egrep可以支持扩展表示是,等价于grep -E


2、sed(流编辑器)


    sed的工作模式:

        sed Stream Editor,流编辑器。对标准输出或文件逐行进行进行处理。

        语法格式:

            stdout | sed [option] "pattern command"    //stout:标准输出; pattern:可选

            sed [option] "pattern command" file     //处理某个文件信息


    sed的选项:

        -n:只打印模式匹配行

sed 'p' sed.txt     //遍历sed.txt文件的每一行然后打印,会打印原行,所以一行会打印2此,p:print(打印)
sed -n 'p' sed.txt     //同上,但不会打印原行
sed -n '/world/p' sed.txt     //匹配包含world的行然后打印这行

        -e:直接在命令进行sed编辑,默认选项(可以处理多次)

sed -n -e '/python/p' -e '/PYTHON/p' sed.txt     //既匹配小写的python又匹配大写的PYTHON,然后打印

        -f:编辑动作保存在文件中,指定文件执行

sed -n -f edit.sed sed.txt //'/python/p'写在edit.sed文件中,然后通过指定edit.sed文件来进行流编辑处理
//实际效果等同于:
sed -n /python/p sed.txt

        -r:支持扩展正则表达式

    sed -n -r '/python|PYTHON/p' sed.txt

        -i:直接修改文件内容    

 sed -n -i 's/python/py/g;p' sed.txt //把sed.txt文件中的python修改为py


    set中的pattern详解(第4、5两种用的最多)

        10command                         //匹配到第10行
        10, 20command                     //匹配从第10行开始,到第20行结束
        10,+5command                     //匹配从第10行开始,到第15行结束,打印第10行后在再打印5行
        /pattern1/command                 //匹配到pattern1的行(满足pattern1条件的行)
        /pattern1/,/pattern2/command     //匹配到pattern1的行开始,到匹配到pattern2的行结束
        10,/pattern1/command             //匹配从第10行开始,到匹配到pettern1的行结束
        /pattern1/, 10command             //匹配到pattern1的行开始,到第10行匹配结束

            

          使用示例:

sed -n "10p" /etc/passwd
sed -n "3,10p" /etc/passwd
sed -n "3,+2p" /etc/passwd
sed -n "/usbmux/p" /etc/passwd
sed -n "/^usbmux/,/^whoopsie/p" /etc/passwd
sed -n "6,/usbmux/p" /etc/passwd
sed -n "/usbmux/,9p" /etc/passwd


    sed中常用的编辑命令(command):

        =:显示匹配内容的行号,不显示行内容
        p:打印
        a:行后追加(append)
        i:行前追加
        r:外部文件读入,行后追加
        w:匹配行写入外部文件
        d:删除
        s/pattern/string/:将行内第一个pattern替换为string
        s/pattern/string/g:将行内全部的pattern替换为string
        s/pattern/string/2:将行内第2个pattern替换为string
        s/pattern/string/2g:将行内从第2个pattern开始替换,所有的都替换为string
        s/pattern/string/ig:将行内pattern全部替换为string,忽略大小写

          使用示例:

sed "/dream/d" dream.txt     //在文件dream.txt中删除匹配到dream的行
sed -i "/lives/a I HAVE A DREAM" dream.txt     //在文件dream.txt中匹配到lives的行后面追加'I HAVE A DREAM'
sed -i "/dream/r test" dream.txt    //将文件test的内容追加到在dream.txt文件中内容匹配到dream的行的后面
sed "/dream/w test" deram.txt     //将dream.txt匹配到dream的行内容保存到test文件中


        反向引用:

            & :引用模式匹配到的整个串,不可以实现部分替换

            \1(数字一):引用模式匹配到的整个串,可以实现部分替换


            使用示例:

sed -i "s/had..p/&s/g" dream.txt     //把文件dream中的所有hadxxp(had开头,p结尾,中间有两个字符)的在其后加's'
sed -i "s/\(had..p\)/\1s/g" deram.txt     //同上
sed -i "s/\(had\).../\1doop/g" dream.txt //部分替换,把had后的三个字符替换为'doop',替换所有


        sed引用变量的注意事项:

            ①当匹配模式中存在变量,则建议使用双引号

            ②sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号


    利用sed查找文件内容:

        例:统计mysql配置文件my.cnf有几个段,每段的段名    ,并统计每个段的参数个数

#!/bin/sh
#
file_name=/home/nginx/shell/testcnf.txt
function get_all_segments
{
    echo "`sed -n '/\[.*\]/p' $file_name | sed -e 's/\[//g' -e 's/\]//g'`"
}
function count_items_in_segment
{
    echo "`sed -n '/\['$1'\]/,/\[.*\]/p' $file_name | grep -v ^\# | grep -v ^$ | grep -v "\[.*\]" | wc -l`"
}
for seg in `get_all_segments`
do
    echo "peizhixuanxiang: $seg  `count_items_in_segment $seg`"
done

    利用sed删除文件内容

10d                     //删除第10行
10, 20d                 //删除第10行,到第20行
10,+5d                     //删除第10行到第15行
/pattern1/d             //删除匹配到pattern1的行(满足pattern1条件的行)
/pattern1/,/pattern2/d     //删除匹配pattern1的行,到匹配到pattern2的行
10,/pattern1/d             //删除第10行,到匹配到pettern1的行
/pattern1/, 10d         //删除匹配到pattern1的行,到第10行(不推荐使用)
(单独一个'$'表示最后一行)

    使用示例:

sed -i '/^#/d;/^$/d' nginx.conf        //删除nginx.conf配置文件的所有注释行和空行('#'在第一个字符)
sed -i '/[:blank:]*#/d' nginx.conf        //删除'#'前有多个空格的行,[:blank:]:表示空格


        所有不以'#'开头的行前加'*'

        sed -i 's/^[^#]/\*&/g'    //[^#]:非'#',&:反向引用


    利用sed修改文件内容

(替换命令)old:既可以为普通字符串,也可以是正则表达式;    new:只能是普通字符串
10s/old/new/                     //把第10行的old内容替换为new
10, 20s/old/new/                 //把第10行,到第20行的old内容替换为new
10,+5s/old/new/                 //把第10行到第15行的old内容替换为new
/pattern1/s/old/new/             //把匹配到pattern1的行的old内容替换为new
/pattern1/,/pattern2/s/old/new/ /把匹配pattern1的行,到匹配到pattern2的行的old内容替换为new
10,/pattern1/s/old/new/         //把第10行,到匹配到pettern1的行的old内容替换为new
/pattern1/, 10s/old/new/         //把匹配到pattern1的行,到第10行的old内容替换为new

    利用sed往文件中追加内容

        例: 

            在test.txt的第10行后追加'Add Line Behend'

  sed -i '10a Add Line Behend' test.txt


3、awk

    awk工作模式:(与sed类似)

        awk是一个文本处理工具,通常用于处理数据并生成结果报告

      语法格式:

        awk 'BEGIN{}pattern{commands}END{}' file_name

        standard output | awk 'BEGIN{}pattern{commands}END{}'


        BEGIN{}:正式处理数据之前执行,固定写法

        parttern:匹配模式

        {commands}:处理命令,可能多行

        END{}:处理完所有匹配数据后执行,固定写法


    awk的内置变量:

$0         //整行内容
$1-$n     //当前行的第1-n个字段(相当于用分隔符分割后的元素)
NF         //当前行的字段个数,也就是有多少列 (Number Field)
NR         //当前行的行号,从1开始计数 (Number Row)
FNR     //多文件处理时,每个文件行号单独计数,都是从0开始 (File Number Row)
FS        //输入字段分隔符。不指定默认以空格或tab键分割(Field Separator)
RS         //输入行分隔符。默认回车换行 (Row Separator)
OFS     //输出字段分隔符。默认为空格(output Field Separator)
ORS     //输出行分隔符。默认为回车换行  (output Row Separator)    
FILENAME //处理文件的文件名    
ARGC     //命令行参数个数
ARGV    //命令行参数数组


          例:

            test.txt的第一行内容:root:x:0:0:root:/root:/bin/bash

awk '{print $0}' test.txt     //输出test.txt的每一行内容
awk 'BEGIN{FS=":"}{print $1}' test.txt //以':' 分割每行内容,输出每一行的第一个字段,这里第一行会输出'root'
awk 'BEGIN{FS=":"}{print NF}' test.txt //输出每一行字段个数,第一行有7个字段

    awk格式化输出值printf

%s:打印字符串
%d:打印十进制数
%f:打印一个浮点数
%x:打印十六进制数
%o:打印八进制数
%e:打印数组的科学技术法形式
%c:打印单个字符串的ASCII码
-:左对齐(对其时要指定位数)
+:有对齐
#:显示8进制在前面加0,显示16进制在前面加0x

使用示例:

awk 'BEGIN{FS=":"}{printf "%#x\n",$3}' /etc/pwass  //以十六进制的形式输出每行的第三个字段,每个字段前加0x


    awk模式匹配的两种用法:

        第一种匹配模式:

            RegExp

            匹配/etc/passwd文件行中含有root字符串的所有行

awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd

            匹配/etc/passwd文件行中以yarn开头的所有行

awk 'BEGIN{FS=":"}/^yarn/{print $0}' /etc/passwd


        第二种匹配模式:

            关系运算符匹配:

<            小于
>            大于
<=            小于等于
>=            大于等于
==            等于
!=            不等于
~            匹配正则表达式
!~            不匹配正则表达式

                (1)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50的所有行信息

 awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd

                (2)、以:为分隔符,匹配/etc/passwd文件中第3个字段大于50的所有行信息

 awk 'BEGIN{FS=":"}$3>50{print $0}' /etc/passwd

                (3)、以:为分隔符,匹配/etc/passwd文件中第7个字段为/bin/bash的所有行信息

 awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd

                (4)、以:为分隔符,匹配/etc/passwd文件中第7个字段不为/bin/bash的所有行信息

 awk 'BEGIN{FS=":"}$7!="/bin/bash"{print $0}' /etc/passwd

                (5)、以:为分隔符,匹配/etc/passwd中第3个字段包含3个以上数字的所有行信息

 awk 'BEGIN{FS=":"}$3~/[0-9]{3,}/{print $0}' /etc/passwd


            布尔运算符匹配:

                ||            或

                &&            与

                !            非


                (1)、以:为分隔符,匹配/etc/passwd文件中包含hdfs或yarn的所有行信息

awk 'BEGIN{FS=":"}$1=="hdfs" || $1=="yarn" {print $0}' /etc/passwd

                (2)、以:为分隔符,匹配/etc/passwd文件中第3个字段小于50并且第4个字段大于50的所有行信息

 awk 'BEGIN{FS=":"}$3<50 && $4>50 {print $0}' /etc/passwd


    awk中表达式的用法:

        算数运算符:

            +                加

            -                减

            *                乘

            /                除

            %                取模

            ^或**            乘方

            ++x                在返回x变量之前,x变量加1

            x++                在返回x变量之后,x变量加1

            --x                在返回x变量之前,x变量减1

            x--                在返回x变量之后,x变量减1


        (比较复杂的awk命令,可以写在文件中,然后通过 "awk -f [awK命令文件名]" 来执行)


    awk动作中国的条件及循环语句:

        条件语句:

    

            if(条件表达式1)

                动作

            else if(条件表达式2)

                动作

            else

                动作

                

        循环语句:

        

            while循环:

                while(条件表达式)

                    动作

                    

            do while循环:

                do

                    动作

                while(条件表达式)

                

            for循环:

                for(初始化计数器;计数器测试;计数器变更)

                    动作    


    awk中的字符串函数:

length(str)                        计算长度
index(str1,str2)                返回在str1中查询到的str2的位置
tolower(str)                    小写转换
toupper(str)                    大写转换    
split(str,arr,fs)                分隔字符串,并保存到数组中(索引从1开始)
match(str,RE)                    返回正则表达式匹配到的子串的位置,正则表达式写在'//'内
substr(str,m,n)                    截取子串,从m个字符开始,截取n位。n若不指定,则默认截取到字符串尾
sub(RE,RepStr,str)                替换查找到的第一个子串
gsub(RE,RepStr,str)                替换查找到的所有子串


    awk的常用选项

        -v        定义或引用变量,将外部变量引用到awk内

        -f        指定awk命令文件(把awk命令放入文件,然后通过-f来指定这个文件来执行)

        -F        指定分隔符

        -V        查看awk的版本号


        例:

num1=20
var1="hello world"
awk -v num2=$num1 -v var2="$var2" 'BEGIN{print num2,var2}'         //变量引用


    awk中数组的用法

定义数组:array=("Allen" "Mike" "Messi" "Jerry" "Hanmeimei" "Wang")
打印元素:        echo ${array[2]}    //Messi
打印元素个数:        echo ${#array[@]}    //6
                     echo ${#array[*]}    //6
打印元素长度:    echo ${#array[3]}    //5——Jerry元素
给元素赋值:        array[3]="Li"
删除元素:        unset array[2];unset array    //注意数组下标问题,删除一个元素后,其他的元素的下标保持不变
分片访问:        echo ${array[@]:1:3}    //访问下标为1到3的元素
元素内容替换:    ${array[@]/e/E}    只替换每个元素的第一个e;${array[@]//e/E}    替换所有的e

        数组的遍历:

for a in ${array[@]};do    echo $a;done


    awk中数组遍历:        

        在awk中,使用数组时,不仅可以使用1.2..n作为数组下标,也可以使用字符串作为数组下标


        当使用1.2.3..n做为下标时,直接使用array[2]访问元素;需要遍历数组时,使用以下形式: 

str="Allen Jerry Mike Tracy Jordan Kobe Garnet"
split(str,array)
for(i=1;i<=length(array);i++)
    print array[i]
awk 'BEGIN{str="Allen Jerry Mike Tracy Jordan Kobe Garnet";split(str,array);for(i=1;i<=length(array);i++) print array[i]}'

        当使用字符串作为数组下标时,需要使用array[str]形式访问元素;遍历数组时,使用以下形式:

            array["var1"]="Jin"

            array["var2"]="Hao"

            array["var3"]="Fang"

            

            for(a in array)            //推荐使用这种方法遍历数组

                print array[a]        //字符串数组下标只能用这种方式遍历  

awk 'BEGIN{array["var1"]="Jin";array["var2"]="Hao";array["var3"]="Fang";for(a in array) print array[a]}'
文章版权及转载声明:

本文由 心月IT技术博客 博主整理于 06-13
若转载请注明原文及出处:http://www.xinyueseo.com/linux/280.html

分享到:
赞(
发表评论
快捷输入:

验证码

    评论列表 (有 0 条评论,人围观)参与讨论