天天看點

Linux Shell 腳本攻略 ---- 第四章 讓文本飛

4.1 正規表達式入門

   1 正規表達式是基于樣式比對的文本處理技術的關鍵所在

   2 正規表達式是用于絕大多數文本處理工具的一種語言

   3 正規表達式的基本組成部分

      正規表達式                 描述             

               ^                      行起始标記      

               $                      行尾标記

                .                      比對任意一個字元

               []                      比對包含在[]之中的任意一個字元

               [^]                    比對除了[]之外的任意一個字元

               [-]                     比對[]中指定範圍内的任意一個字元

               ?                      比對之前的項1次或0次

               +                      比對之前的項1次或多次

               *                       比對之前的項0次或多次

               {n}                    比對之前的項n次

               {n,}                   比對之前的項至少n次

               {n,m}               比對之前的項至少n次最大m次

    4 為了比對一個IP位址,可以使用下面的正規表達式

         [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}

         我們知道IP位址通常是由點号分割的4個整數,每個整數的值是0-255

    5 我們在字元前面放一個”\",這種做法是稱為對字元的轉制

4.2 用grep在檔案中搜尋文本

    1 grep指令是UNIX中用于文本搜尋的大師級工具,它能夠接受正規表達式和通配符

    2 在檔案中搜尋一個單詞: grep word file

    3 grep指令也可以對多個檔案進行搜尋: grep word file1 file2 file3...

    4 如果想要列印包含word之外的所有行可使用: grep -v word file

    5 統計檔案或文本中包含比對字元串的行數: grep -c word file

    6 列印出包含比對字元串的行數: grep -n word file

    7 如果需要在多級目錄中對文本進行遞歸搜尋,可以使用: grep word path -R -n

    8 忽略樣式中的大小寫: grep -i word file

    9 列印出比對檔案之前或之後的行

       要列印比對某個結果之後3行: grep word -A 3 file

       要列印比對某個結果之前的3行: grep word -B 3 file

       要列印比對某個結果的之前及之後3行: grep word -C 3 file

4.3 用cut按列切分檔案

    1 cut是一個幫我們将文本按列進行切分的小工具,它也可以通過指定定界符

    2 為了提取第一個字段或列,可以使用下面的方法

        cut -f field_list file  // field_list是要顯示的列

    3 cut -f 2,3 file // 這條指令将顯示第2,第3列

    4 我們也可以利用-complement選項對提取的字段進行補集運算,假設有多個字段,你希望列印出除了第3列之外的所有列,則可以使用: cut -f3 --complement file

    5 要指定字段的定界符,使用-d選項: cut -f2 -d";" file // 指令顯示第2列,用";"做為分割符

    6 如果要切分出第n到m個字元可以使用: cut -cn-m file

4.4 sed入門

    1 sed是stream editor(流編輯器)的縮寫,它是文本進行中非常重要的工具,它能夠完美的配合正規表達式使用,功能不同反響

    2 sed可以替換給文本中的字元串,它可以利用正規表達式進行比對

       sed 's/pattern/replace_string/' file

    3 如果使用-i選項,可以将替換結果應用于原檔案: sed -i 's/pattern/replace_string/' file

    4 用sed移除空白行: sed '/^$/d' file 

    5 利用管道組多個sed指令這種方法可以用下面的方式替換: sed expression | sed expression 等價于sed 'expression ; expression'

4.5 awk入門

    1 awk腳本的結構基本如下所示: awk 'BEGIN{statement} pattern{statement}END{statement}'

    2 一個awk腳本通常有三個部分組成:BEGIN語句塊,END語句塊和能夠使用模式比對的語句塊。這三個部分是可選的,它們中的任何一個部分都可以不出現在腳本中,腳本通常包含在單引号中或雙引号中

    3 awk指令的工作方式

      (1) 執行BEGIN{statement}語句塊中的語句

      (2) 從檔案或stdin中讀取一行,然後執行pattern{statement},重複這個過程,直到檔案全部讀取完畢

      (3) 當讀至輸入流末尾的時候,執行END{statement}語句塊

    4 BEGIN語句塊在awk開始從輸入流中讀取行之前被執行,這是一個可選的語句塊,諸如變量的初始化,列印輸出表格的表頭語句等等

    5 END語句塊和BEGIN類似,END語句在awk從輸入流中讀取完畢之後被執行,像列印所有行的結果這類資訊一般都是放在END語句塊中執行

    6 最終要的部分是pattern語句塊中的部分,這個語句塊同樣也是可選的,如果不提供,則預設執行print,即列印每一個讀取的行

    7 當使用不帶參數的pring時,它會打出目前行。關于print,需要記住的是:當pring的參數是以逗号進行分割時,參數列印則以空格做為定界符,在awk的print中雙引号是被當做拼接操作符使用的

    8 awk的一些特殊變量

       NR: 表示記錄數量,在執行的過程中相當于目前行号

       NF: 表示字段數量,在執行過程中對應于目前行的字段數

       $0: 這個變量包含執行過程中目前行的文本内容

       $1: 這個變量包含第一個字段的文本内容

       $2: 這個變量包含第二個字段的文本内容

    9 通常grep是預設讀取一個檔案的所有行,如果隻想讀取某一行,可以使用getline

    10 awk有很多内置的函數

         length(string): 傳回字元串的長度

         index(string, search_string): 傳回search_string在字元串中的出現的位置

         split(string, array, delimiter): 用定界符生成一個字元串清單,并将該清單存入數組

4.6 替換文本或檔案中的字元串

    1 可以使用下面的方式替換一個字元串或樣式

       sed 's/pattern/replace_string/g' file //這條指令會替換所有比對到的項,/g的意識是全局(global),這就意味着它會替換檔案中所有比對的内容

    2 當檔案名傳遞給sed的時候,sed将輸出寫到stdout,如果不想把輸出結果輸送到stdout,而是将更改儲存到原檔案中可以使用-i選項 sed 's/pattern/replace_string/g' -i file  

4.7 按列合并檔案

    1 可以使用paste指令實作按列拼接: paste file1 file2 file3

    2 預設的定界符是制表符,也可以使用-d來明确指定定界符

       paste file1 file2 -d "," // 指定定界符是","

4.8 列印檔案或行中的第n個單詞或列

    1 用下面的指令列印第五列

       awk '{print $5}' file // 這個指令将列印檔案file的第五列

    2 要列印從M行到N行這個範圍的所有文本,使用下面的文法

       awk 'NR==N , NR==M' file

    3 指令tac可以做到逆序列印檔案

       seq 5 | tac // 這個指令将輸出5 4 3 2 1

       tac file // 這個指令将逆序列印處檔案file

    4 用awk實作head和tail還有tac 

       awk 'NR <= 10' file // 這個指令預設列印處檔案file的前10行

       awk '{buffer[NR%10]=$0}END{for(i=1;i<11;i++)print buffer[i%10]} file // 這個指令預設列印檔案file的最後10行

       awk '{buffer[NR]=$0}END{for(i=NR;i>0;i--)print buffer[i]}' file // 這個指令預設列印逆序列印出檔案file

繼續閱讀