本文作者:心月

linux文本處理三劍客(grep、sed、akw)命令選項整理

心月IT博客 2019-06-13
摘要: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 [akw命令文件名]" 來執行)


    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]}'


文章版權及轉載聲明:

作者:心月 本文地址:http://www.rawkpk.live/linux/280.html發布于 2019-07-01
文章轉載或復制請以超鏈接形式并注明出處心月IT博客

分享到:
贊(

發表評論

快捷輸入:

    評論列表 (有 0 條評論,人圍觀)參與討論