20150915 Linux 數組 sed awk

第一部分數組:html

bash腳本編程:    
    變量:變量名   ,命名的命名空間    
    數組:連續的多個獨立內存空間;每一個內存空間至關於一個變量;    
        數據元素的引用:數組名[索引]前端

    bash 4.0+之後版本支持二種類型:    
        傳統數組(基本數組):索引爲數字,從0開始編號;    
            declare -a ARRAY_NAME    
        關聯數組:索引能夠自定義,可使用任意字符串作索引;    
            declare -A ARRAY_NAME正則表達式

        支持稀疏格式(指賦值第一個後,可隨意跳到第3個或四、7等,可不連續)shell

    數組元素的賦值方式:    
        (1) 一次只賦值一個元素    
            array[index]=value    
        (2) 一次賦值所有元素    
            array=("val1" "val2" ...)   #從索引0,1,2….開始,順序的    
        (3) 指定索引進行賦值    
            array=([0]="val1" [3]="val2")   #區別指名索引,稀疏格式    
        (4) read -a array  #基於,多個一個元素在一個數組中express

      示例:將變量tom ,jerry,ben保存在一數組arrary當中,利用array數組apache

下面加索引的方式。進行調用編程

     p_w_picpath

    引用元素:${array[index]}vim

    長度(數組的長度):${#array[*]}, ${#array[@]}數組

    練習:利用bash生成10個隨機數值,保存於數組中;要此些數組排序    
        $RANDOM (從0至32767) 示例:echo $RANDOM(注意必須是大寫)bash

 p_w_picpathp_w_picpath

 

第二部分:Sed命令    
    
    grep, sed, awk    
        grep: 文本搜索工具;egrep, fgrep    
        sed: stream editor, 流編輯器;    
        awk(gawk):文本格式化工具,報告生成器

第一:sed運行方式

        sed一次讀取一行。能夠是指定範圍的行,或者表達式。

一次讀一行後運行在本身的模式空間(pattern space),針對文本進行

處理。判斷是否符合判斷條件進行編輯操做,符合條件處理後輸出

到屏幕當中。即打印模式空間(默認)不論是否成功。

p_w_picpath

第二:sed命令:

1) 基本正則表達式元字符:    
        字符匹配:., [], [^]    
        次數匹配:*, \?, \+, \{m,n\}, \{n\}    
        位置錨定:^, $, \<, \>    
        分組及引用:\(\), \1, \2, ...    
         多選一:a|b|c

     vim編輯中文本的查找替換:    
        地址定界s/要查找的內容/替換爲的內容/    
          要查找的內容:可以使用正則表達式    
          替換爲的內容:不支持正則表達式,但支持引用前面正則表達式分組中的內容    
          地址定界:%, startline,endline

  2)語法      

語法:sed [OPTION]... {script} [input-file]...

工做機制:每次讀取一行文本至「模式空間(pattern space)」中,在模式空間中完成處理;將處理結果輸出至標準輸出設備;

  A) Option選項

      -r: 支持擴展正則表達式; 
      -n: 靜默模式; (指只打印靜默默認的行,沒有要求輸出不作輸出操做) 
      -e script1 -e script2 -e script3:指定多腳本運行; 
      -f /path/to/script_file:從指定的文件中讀取腳本並運行; 
      -i: 直接修改源文件;(默認sed不會對源文件做操做)

  B)腳本

   其中腳本包括地址定界和編輯命令二個功能

     地址定界: (類型VIM) 
       #: 指定行;  :#  指定行 
       $: 最後一行; 
      /regexp/:任何可以被regexp所匹配到的行; 
      \%regexp%:同上,只不過換做%爲regexp邊界符; 
      /regexp/| : 
      \%regexp%| :匹配時忽略字符大小寫; 
      startline,endline: 
      #,/regexp/:從#行開始,到第一次被/regexp/所匹配到的行結束,中間的全部行; 
      #,#  

示例:sed ‘1,4d’ /etc/fstab 刪除1至4行

p_w_picpath 
  /regexp1/,/regexp2/:從第一次被/regexp1/匹配到的行開始,到第一次被/regexp2/匹配到的行結束,中間的全部行; 
   #,+n:從#行開始,一直到向下的n行; 
  first~step:指定起始行,以及步長; 
     1~2,  說明從1開始,步進爲2,這樣爲1,3,5,7.。。。奇數行

     2~2 ,說明 從2開始,步進爲2,這樣爲2,3,4,6,8 。。。偶數行

sed的編輯命令 
     d: 刪除模式空間中的行;

示例:不顯示/etc/fstab中以UUID開始的行

p_w_picpath 
=:顯示行號; (不在同一行)

示例 sed ‘1,4=’ /etc/fstab

p_w_picpath 
a \text:附加text

示例  sed '/^UUID/a \newline' /etc/fstab  同時也能夠轉意再添加一行

  sed '/^UUID/a \newline \n secondline' /etc/fstab

p_w_picpath

p_w_picpath

i \text:插入text,支持\n實現多行插入; (在符合條件行以前)

p_w_picpath

  c \text:用text替換匹配到的行;    
p_w_picpath

p: 打印模式空間中的行; (默認狀況下,sed會打印模式空間的行,當

知足條件時會打印二行)

p_w_picpath

  針對靜默空間的行採用-n選項

p_w_picpath

s/regexp/replacement/:替換由regexp所匹配到的內容爲replacement; 
       g: 全局替換;

p_w_picpath 
              
w /path/to/somefile:把指定的內容另存至/path/to/somefile路徑所指定的文件中;

示例:將奇數行保存至/tmp/fstab.odd文件當中

p_w_picpath

  r /path/from/somefile:在文件的指定位置插入另外一個文件的全部內容,完成文件合併;

示例:將/etc/issue文件中插入到第五行後,完成文件合併

p_w_picpath

練習: 
(1) 刪除/boot/grub/grub.conf文件中全部行的行首的空白字符; 

sed 's/^[[:space:]]\+//' /boot/grub/grub.conf    #//替換爲空  全文件查找不用使用定界

   可在s前填加地址定界,例如第10行。。。

p_w_picpath

     刪除空白行

 

 sed ‘/^$/d’ /etc/grub2.cfg


(2) 刪除/etc/fstab文件中全部以#開頭,後跟至少一個空白字符的行的行首的#和空白字符; 
   

 sed 's/^#[[:space:]]\+//' /etc/fstab    #\+匹配次數1


(3) 把/etc/fstab文件的奇數行另存爲/tmp/fstab.3; 
   

  sed '1~2w /tmp/fstab.3' /etc/fstab


(4) echo一個文件路徑給sed命令,取出其基名;進一步地,取出其路徑名; 
  取基名:echo "/etc/sysconfig/network-scripts/" | sed 's@^.*/\([^/]\+\)/\?$@\1@' 
  取路徑名:echo "/etc/sysconfig/network-scripts/" | sed 's@[^/]\+/\?$@@'

 

sed命令另外一個稱做"hold space"的內存空間:保持空間

p_w_picpath

    pattern space這加工廠,hold space爲倉庫。用的時候還能夠取回。

只可以在pattern space編輯。

  高級命令: 
    h:用模式空間中的內容覆蓋保持空間的內容; 
    H:把模式空間中的內容追加至保持空間中內容的後面; 
    g:從保持空間中取到其內容,並將其覆蓋模式空間中的內容; 
    G:從保持空間中取到其內容,並將其追加在模式空間中的內容的後面; 
    x:把保持空間和模式空間中的進行交換; 
    n:讀取匹配到的行的下一行至模式空間;(會覆蓋模式空間中的原有內容); 
    N:讀取匹配到的行的下一行至模式空間,追加在模式空間中原有內容的後面; 
    d:刪除模式空間中的內容; 
    D:刪除多行模式空間中的首行;

注意:命令功能可以使用!取反(針對地址取反);分號可用於分隔腳本;

示例:

sed '1,3!d' /etc/fstab   表示1至3行以外行刪除掉,這裏針對地址定界取反

p_w_picpath    
sed 'G' /etc/issue: 在文件中的每行後方添加空白行; 由於模式空間爲空 
p_w_picpath

sed '$!d' /etc/fstab:保留最後一行;   $表示最後一行

p_w_picpath    
sed '/^$/d;G' /etc/issue: 保證指定的文件每一行後方有且只有一個空白行;

  (若是前爲空白行刪除,非空白行後面添加一個空白行)

  ^$爲空白行  
  sed 'n;d' /etc/issue:保留奇數行; 從外命令分號分隔開(每讀的下一行爲偶數行)

當讀1行第時,這時第2行會刪除以此類推)

p_w_picpath

  sed -n '1!G;h;$p' /etc/issue   $p打印最後一行,第一行不作get,不從

保存空間取內容。示例:左側第一排爲輸入文件,中間一排爲模式空間,第三排

爲保存空間。輸出爲4,3,2,1;功能:逆序顯示文件內容

-n沒有要求輸出,不作輸出操做

tac 命令用於逆向顯示

p_w_picpath

    sed '$!N;$!D' /etc/issue  顯示最後一行

p_w_picpath

  sed命令:    
       -e 'script' -e 'script'    
         'script;script;script'

          script    
          script    
          script

        -f /path/from/script


第三部分:AWK

1)定義及工做方式

  AA:定義

      首先awk爲c語言風格

awk:    
    grep, sed, awk (文件格式化輸出工具)    
        grep: 文本過濾器    
        sed: 行編輯器    
        awk: 報告生成器(早期在Unix版本)

    AWK a.k.a Aho, Weinberger, Kernighan

    Gnu AWK, gawk(awk是指向gawk的連接)

    ls –l `which awk`

p_w_picpath

   awk功能相比sed更增強大支持if語句、條件判斷、數組、自定義函數等功能

BB:工做模式

  一次讀一行到本身的命名空間,不對每行作操做只針對符合條件的行進行編輯,

進行地址定界。在awk裏面稱爲模式。

  將一行文本信息,按照用戶指定的格式或分隔符切成n片。保存到awk指定的

變量當中。引用整行用$0,引用某段利用$1,$2。。。進行引用

 p_w_picpath

  2)基本語法    
    awk [options] 'program' file file ...    
    awk [options] 'PATTERN{action}' file file ...

awk的相似cut,每一個 program可分解爲pattern{action}

內置一次讀一行(循環處理每一行之意),其中action經常使用

的包括print(簡單輸出)、printf(格式化輸出)

示例: 顯示/etc/passwd以冒號分隔的第一段

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

 p_w_picpath

 -F CHAR:輸入分隔符   ‘{ }’ 表示引用本身的腳本,$1第一字段

加$表示引用字段

 A、awk的輸出

  print item1, item2,...

 itme一、item2可爲字符、也能夠爲字符串(必須雙引號)    
  要點:    
  (1) 各項目之間使用逗號分隔,而輸出時則使用輸出分隔符分隔;

各項目之間輸出以空格分隔,逗號有多個條之意

p_w_picpath

 若是$1,$3之間爲空後,將二個項目相聯

p_w_picpath    
 (2) 輸出的各item能夠字符串或數值、當前記錄的字段、變量或awk的表達式;

數值會被隱式轉換爲字符串後輸出;    
 (3) print後面item若是省略,至關於print $0;輸出空白,使用pirnt "";

p_w_picpath

 B、awk的變量    
        內置變量,自定義變量,注意內部引用變量不須要$

    2.1 內置變量 (awk自帶的)    
    FS:Field Seperator, 輸入時的字段分隔符    
        # awk 'BEGIN{FS=":"}{print $1,$7}' /etc/passwd

    RS:Record Seperator, 輸入行分隔符    
    OFS: Output Field Seperator, 輸出時的字段分隔符;    
    ORS: Outpput Row Seperator, 輸出時的行分隔符;

    NF:Numbers of Field,每一行的字段數 :默認以空格進行統計。無空格爲1

p_w_picpath    
    NR:Numbers of Record, 行數/號;全部文件的一併計數; 進行行統計

示例:awk ` (printf NR,$0)’ /etc/fstab /etc/issue

p_w_picpath

      若是NR前加$NR表示讀取字段數的值(原文件左側

awk '{print $NF}' /etc/grub2.cfg  以最後一段爲4(該語句含義打印第四4個字段,

若是是其它字段則變化,實際爲打印最後一個字段的值)

p_w_picpathp_w_picpath

    FNR:行數;各文件分別計數;    
p_w_picpath

   ARGV:數組,保存命令自己這個字符,awk '{print $0}' 1.txt 2.txt,意味着ARGV[0]保存awk,    
   ARGC: 保存awk命令中參數的個數;    
   FILENAME: awk正在處理的當前文件的名稱;

  2.2 可自定義變量    
        -v var_name=VALUE    -v表示給一個變量賦值

        變量名區分字符大小寫;

        (1) 能夠program中定義變量;    
        (2) 能夠命令行中經過-v選項自定義變量;

示例:定義變量test,在打印時引用變量,加到輸入字段輸出

p_w_picpath

  示例:打印每一個及最後一個字段(冒號分隔)

p_w_picpath

   awk -F: '{print $1,$NF}' /etc/passwd   命令可修改成

   awk -v FS=: '{print $1,$NF}' /etc/passwd   其中FS爲變量,同時

FS爲內置輸入時的分隔符。這裏爲:(冒號)

p_w_picpath

  # awk -v FS=: -v OFS=# '{print $1,$NF}' /etc/passwd

使用OFS爲輸出時的分隔符,這樣字段1和最後一個字段時間以#號分隔

    三、awk的printf命令(f表明format ,可定義相應的格式)

        命令的使用格式:printf format, item1, item2,...

每一個itme都會對應相應的format

        要點:    
        (1) 要指定format;    
        (2) 不會自動換行;如需換行則須要給出\n    
        (3) format用於爲後面的每一個item指定其輸出格式;

        format格式的指示符都%開頭,後跟一個字符:    
            %c: 顯示字符的ASCII碼;    
            %d, %i: 十進制整數;    
            %e, %E: 科學計數法顯示數值;    
            %f: 顯示浮點數;    
            %g, %G: 以科學計數法格式或浮點數格式顯示數值;    
            %s: 顯示字符串;    
            %u: 顯示無符號整數;    
            %%: 顯示%自身;

        修飾符:    
            #:顯示寬度  3表明三個字符的寬度    
            -:左對齊    
            +:顯示數值的符號    
            .#: 取值精度

示例:

awk -F: '{printf "UID:%d\n",$3}' /etc/passwd

以UID:xxxx;顯示%d表示十進制數,\n表示換行,將$3放到

format中進行顯示

p_w_picpath

  將修飾符添加到%d前端例如 %10d表示寬度爲10,%.10d表示

10個字符,前會以0補充。(默認靠右對齊如%-10d 左對齊)

p_w_picpath

p_w_picpath

    四、awk輸出重定向 (未講解)    
        print items > output-file    
        print items >> output-file    
        print items | command

示例:將輸出保存到/tmp/51cto/awkout文件中

p_w_picpath

        特殊文件描述符:    
        /dev/stdin: 標準輸入    
        /dev/stdout: 標準輸出    
        /dev/stderr: 錯誤輸出

    五、awk的操做符

        算術操做符:    
            x+y    
            x-y    
            x*y    
            x/y    
            x**y, x^y    求次方    
            x%y   取模    
             -x:負值    
            +x:轉換爲數值

        字符串操做符:鏈接  不須要任何,不可以使用逗號,

        賦值操做符:    
            =    
            +=    
            -=    
            *=    
            /=    
            %=    
            ^=    
            **=

            ++     自加    
             --      自減

            若是模式自身是=號,要寫爲/=/

        比較操做符:    
            <    
            <=    
            >    
            >=    
            ==    
            !=    
            ~:模式匹配,左邊的字符串可以被右邊的模式所匹配爲真,不然爲假;    
            !~:

        邏輯操做符:    
            &&: 與    
            ||:或

        條件表達式: (雙分支語句)    
        selector?if-true-expression:if-false-expression

   selector是個挑選器,若是真執行if-true-express分支,假執行if-false分支

示例: 

# awk -F: '{$3>=1000?utype="common user":utype="admin or system user";print $1,"is",utype}'

/etc/passwd

        函數調用: (支持內部或外部函數)    
        function_name(argu1,argu2)  #以函數名加用戶參數的形式指定。

 

  後續進行awk的pattern和Action

六、模式

   awk pattern支持的五種類型

  (1) Regexp: 格式爲/PATTERN/    模式匹配到的行進行處理,不然不進行處理 
      僅處理被/PATTERN/匹配到的行;

示例 awk '{print $3}' /etc/fstab 

p_w_picpath

   以UUID開始的行

p_w_picpath 
  (2) Expression: 表達式,其結果爲非0或非空字符串時知足條件; 
      僅處理知足條件的行; (利用比較操做符)

示例:awk -F: '$3>=1000 {print $1,$3}' /etc/passwd

p_w_picpath

awk -F: '$NF~/bash$/ {print $1,$NF} ' /etc/passwd

   $NF表示結尾 $NF表明最後一個字段

      ~:模式匹配,左邊的字符串可以被右邊的模式所匹配爲真,不然爲假; 
      !~

     bash$表示以bash結尾

p_w_picpath

awk -F: '$NF!~/bash$/ {print $NF} ' /etc/passwd   最後字段非bash結尾

p_w_picpath    

  (3) Ranges: 行範圍,此前地址定界,  

        NR   行號 
       僅處理範圍內的行

awk -F: 'NR>=15 && NR<=20 {print $1,$NF}' /etc/passwd  輸出15至20行的內容

p_w_picpath 
(4) BEGIN/END: 特殊模式,

僅在awk命令的program運行以前(BEGIN)或運行以後(END)執行一次;

示例:在運行以後打印一行」=====usernme====shell====」

p_w_picpath

Begin和End之間或以後使用相應變量,或提示信息等 
(5) Empty:空模式,匹配任意行;(若是未指定行說明是全部行)

p_w_picpath

七、經常使用的action

    (1) Expressions    表達式 :比較、算術表明式等,多個用分號分隔 
    (2) Control statements        控制語句 
    (3) Compound statements   組合語句 
    (4) input statements   輸入語句 
   (5) output statements  輸出語句  print   printf

八、控制語句

    8.1 if-else 
      格式:if (condition) {then body} else {else body}  注意:條件是小括號

# awk -F: '{if ($3>=500) {print $1,"is a common user"} else {print $1, "is an admin or system user"}}' /etc/passwd
# awk '{if (NF>=8) {print}}' /etc/inittab #當字段數大於打印整行內容  NF字段數,無else直接 print(單分支)

       NR行號

# awk '{if (NF>=8) {print $0} else {print NR,$0}}' /etc/inittab #大於8顯示行號,不大於8不顯示行號

p_w_picpath

   判斷用戶id與組id是否一致

  # awk -F: '{if ($3==$4) {print $1, "good user"}}' /etc/passwd

p_w_picpath

  8.2 while (通常用於針對某字段作相似處理) 
      格式:while (condition) {while body}    條件爲真執行

    # awk '{i=1; while (i<=NF){printf "%s ",$i;i+=2};print ""}' /etc/inittab

           顯示奇數字段,print可以換行 
 

 # awk '{i=1; while (i<=NF){if (length($i)>=6) {print $i}; i++}}' /etc/inittab

         字段串長度大於6顯示

   length()函數:取字符串的長度

      %s: 顯示字符串;

8.3 do-while循環

    至少執行一次,無論條件是否爲真或假 
     格式:do {do-while body} while (condition) 

8.4 for循環 
  格式:for (variable assignment; condition; iteration process) {for body} 

# awk '{for (i=1;i<=NF;i+=2){printf "%s ",$i};print ""}' /etc/inittab  顯示奇數字段  
# awk '{for (i=1;i<=NF;i++){if (length($i)>=6) print $i}}' /etc/inittab

   for循環可用來遍歷數組元素: 
         語法:for (i in array) {for body}

8.5 case語句 
  語法:switch (expression) {case VALUE or /RGEEXP/: statement1;... default: stementN}

      都不知足執行default語句

8.6 循環控制 
      break   提早終止循環 
      continue    提早終止本輪循環   針對字段

8.7 next 【針對行】 
      提早結束對本行的處理進而提早進入下一行的處理; 

       # awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd   #顯示奇數用戶的id  
       # awk -F: '{if(NR%2==0) next; print NR,$1}' /etc/passwd

九、數組

     傳統數組:Index編號從1開始; 
     關聯數組:

       array[index-expression]

  index-expression: 可使用任意字符串; 若是某數組元素事先不存在,那麼在引用時,

awk會自動建立此元素並將其初始化爲空串;所以,要判斷某數組是否存在某元素,

必須使用「index in array」這種格式;

                A[first]="hello awk"    
                print A[second]

     要遍歷數組中的每個元素,須要使用以下特殊結構: 
        for (var in array) {for body}  #var保存的是array的每個索引

            其var會遍歷array的索引;

示例: 如附字符串時須要在數組中以雙引號 test[「 字符串」]

p_w_picpath

利用for循環語句輸出

# awk 'BEGIN{test["mon"]="monday";test["tue"]="tuesday";for (i in test){print test[i]}}'

p_w_picpath

        state[LISTEN]++ 
       state[ESTABLISHED]++

      NF字段數;$NF最後一個字段

# netstat -tan | awk '/^tcp/{++state[$NF]}END{for (s in state) {print s,state[s]}}'

顯示連接的個數,^tcp協議類型,state數組,將狀態保存到數組當中,當有一個元素時

加1用++表示,awk自動循環。這裏數組state當中包括二種listen的數量和establised數量。

最後用end在最後面一次輸出相應的值

p_w_picpath

# awk '{ip[$1]++}END{for (i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

統計每一個IP地址請求次數,須要利用httpd服務

AA:啓動httpd服務的80端口

p_w_picpath

BB:編輯 vim /var/www/html/index.html, 隨意輸入內容

p_w_picpath

CC:運行 ab -n 10000 -c 100 http://192.168.6.184/index.html 模擬請求

ab爲apache測試工具

p_w_picpath

DD:查看/var/log/httpd/access_log目錄內容

   顯示客戶端對服務端 的請求

p_w_picpath

EE:利用輸出語句,彙總相關信息

   統計每一個IP地址請求次數

p_w_picpath

 

刪除數組元素: 
       delete array[index]

十、awk的內置函數

split(string,array[,fieldsep[,seps]]): 
        功能:將string表示的字符串以fieldsep爲分隔符進行切片,

並切片後的結果保存至array爲名的數組中;數組下標從1開始;

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

     user[1]="root", user[2]

       此函數有返回值,返回值爲切片後的元素的個數

# netstat -tn | awk '/^tcp/{lens=split($5,client,":");ip[client[1]]++}END{for (i in ip) print i,ip[i]}'

顯示第五個這段冒號前的地址,保存到數組client當中進行統計

p_w_picpath      

length(string) 
      功能:返回給定字串的長度

substr(string,start[,length]) 
       功能:從string中取子串,從start爲起始位置爲取length長度的子串;

    博客:sed和awk的使用

相關文章
相關標籤/搜索