天天看點

shell小結

1.什麼是Shell及其特點:

Shell是指令解釋器,它接收應用程式或使用者指令,然後調用作業系統核心。
Shell是一個功能強大的程式設計語言,易編寫、易調試、靈活性強。           
shell小結

2.Shell類型檢視及配置:

檢視主機上有哪個shell:#cat /etc/shells
檢視目前所用shell:#echo $SHELL
更改目前shell: #chsh /bin/sh

sh是bash的軟連結:
    [root@centos7 ~]#ll /bin/ |grep bash
    -rwxr-xr-x. 1 root root     964608 Oct 31  2018 bash
    lrwxrwxrwx. 1 root root         10 Jul 17  2019 bashbug -> bashbug-64
    -rwxr-xr-x. 1 root root       6964 Oct 31  2018 bashbug-64
    lrwxrwxrwx. 1 root root          4 Jul 17  2019 sh -> bash           

3.Shell腳本:

(1)開頭:#!/bin/bash
(2)啟動shell及執行權限與否:
    ./*.sh等價于sh ./*.sh等價bash ./*.sh,腳本執行是在重新啟動一個子shell中執行。./*.sh需要加x權限則$0生效,sh與bash有無x對$0生效。
    source ./*.sh等價于. ./*.sh,腳本執行是在目前shell程序中執行,無需重新啟動一個子shell。 $0則無效。
    【./*.sh執行腳本需要腳本有執行權限,這由于本質是腳本需要自己執行,是以需要執行權限;
       而其餘的則不需要,這由于是本質是bash解釋器幫你執行腳本,是以腳本本身不需要執行權限】
(3)多指令操作:可以一行一行的寫,不需要分号隔離或可以用上&&。           

4.Shell變量:

(1)系統變量:
    [root@centos7 ~]#echo $HOME $PWD $USER $SHELL
    /root /root root /bin/bash
(2)自定義變量:變量=值 【等号兩邊沒有空格,這裡的等号是指派】
    定義變量:a=10
    檢視值:  echo $a
    撤銷變量:unset a 
    
    聲明一個靜态變量:readonly變量 
    【不能unset,但可以退出此session就撤銷了。靜态變量聲明時需要指派,否則聲明後不可指派
      非靜态變量,可以轉化為靜态變量:readonly 變量名】
(3)變量定義規則:
    變量名稱是由字母、數字和下劃線組成,但是不能以數字開頭;環境變量名建議用大寫。
    等号兩側不能有空格。
    在bash中,變量預設類型都是字元串類型,無法直接進行數字運算。
    變量的值若有空格,需要使用雙引号或單引号括起來。
    
    例子如下:
        [root@centos7 ~]#4ab=123
        bash: 4ab=123: command not found...
        [root@centos7 ~]#
        [root@centos7 ~]#_4ab=123
        [root@centos7 ~]#echo $_4ab 
        123
        [root@centos7 ~]#
        [root@centos7 ~]#a =3
        bash: a: command not found...
        [root@centos7 ~]#a= 3
        bash: 3: command not found...
        [root@centos7 ~]#a=3
        [root@centos7 ~]#echo $a
        3
        [root@centos7 ~]#
        [root@centos7 ~]#b=3+8
        [root@centos7 ~]#echo $b
        3+8
        [root@centos7 ~]#
        [root@centos7 ~]#c=345 ad
        bash: ad: command not found...
        [root@centos7 ~]#c="345 ad"
        [root@centos7 ~]#echo $c
        345 ad
        [root@centos7 ~]#
(4)可把變量提升為全局環境變量,可供其他shell程式使用:
    export 變量名
    【可以先聲明再指派或聲明的同時指派:export a或export a=100】
(5)特殊變量:
    $n,n為數字,$0代表腳本名稱,$1-$9表示第一個到第九個參數,十及以上的參數需要用大括号${10}表示。 $n參數之間是以空格為分隔符。
    $#,擷取所有輸入參數的個數,常用于循環。
    $*與$@,都是擷取指令行中所有的參數,但$*把所有的參數看成一個整體;$@把每個參數區分對待。
    $?,最後一次執行的指令傳回狀态。值為0,證明上一個指令執行正确;值為非0,證明上一個指令執行不正确。           

5.運算符:

(1)基本文法:
    一種:$((運算式))或$[運算式]。+、-、*、/、%對應加、減、乘、除、取餘。例子:$(((2+3)*4))等價于$[(2+3)*4]
    另一種:expr +、-、\*、/、%對應加、減、乘、除、取餘。【expr運算符間要有空格】。例子:expr `expr 2 + 3` \* 4
    
    【bc、expr、let可用于數值計算:bc可以用于整數或小數的計算,而expr與let隻能用于整數的計算
        輸入:整數,let和expr都無法進行浮點運算,但是bc和awk可以。
        輸出:bc、expr可直接顯示計算結果;let則丢棄計算結果,可通過傳遞結果到變量,取變量值獲得計算結果。
        例子:let a=3+4.4  echo $a
             expr `expr 2 + 3` \* 4
             echo 9+4.4|bc 或echo 9+4.4"|bc
    】           

6.條件判斷:[ condition ] 或 [[ condition ]]

(1)基本文法:
    [ condition ] 【注意condition前後要有空格,條件非空即為true,[ a ]傳回true;[]傳回false。】
    condition中的條件操作:所判斷的内容與條件符号之間要空格。例子:a=abc  [ $a == abc ];若是寫成了[ $a==abc ]這是恒為true,由于$a==abc相當于5==abc并不是比較判斷而是直接非空。
(2)[ ]與[[ ]]的差別:    
    相同點:二者都可以進行數字比較判斷或字元串比較判斷。
    
    不相同點:-n或-z方式判斷變量是否為空時,[]形式,需要變量加上雙引号,而[[ ]]則不需要。例子:[ -n "var"] 或 [[ -n var]]
            -a(and與)或-o(or或)對多個條件進行連接配接時,[]形式把-a或-o放在[]中,而[[ ]]不能使用-a或-o進行多條件連接配接。 例子:[ 4 -gt 2 -a 4 -lt 5 ]
            &&或||進行多條件連接配接時,[]形式把&&或||放在[]外邊,而[[ ]]形式把&&或||放在[[]]裡邊。[ 4 -gt 2 ]&&[ 4 -lt 5 ]或[[ 4 -gt 2 && 4 -lt 5 ]]
            使用符号"=~"比對正則表達時,隻能使用[[ ]]。例子:[[ $var =~ [0-9]{11} ]]
            當使用">"或者"<"判斷字元串的ASCII值大小時,如果使用[]則加上轉義符\。例子:[ a \< b]
(3)常用判斷條件:
    數字比較判斷:-lt(le)ss than)小于、 -gt(greater than)大于
            -eq(equal)等于、      -le(less)小于
             -le(less equal)小于等于、-ge(greater equal)大于等于
         
    字元串判斷:【盡量把變量或字元串加上雙引号進行比較判斷】
        當進行字元串判斷時,可以用[ condition ] 或[[ condition ]]進行判斷,但[ -n "var" ]或[ -z "var" ]時都需要加上雙引号;而[[ -n var ]]或[[ -z var ]]不需要加上雙引号。
        =或==都可以表示字元串相同判斷。
        !=是進行字元串不相同判斷。
        -n是字元串為非空則真,可以了解為nozero。
        -z是字元串為空則真,可以了解為zero。
(4)檔案測試判斷:【用相當路徑時,注意目前所處位置及檔案的路徑;建議用上絕對路徑】
    -e是檔案或目錄存在為真。例子:[ -e path ]
    -f是檔案存在為真。例子:[ -f file_path ]
    -d是目錄存在為真。例子:[ -d dir_path ]
    -r -w -x分别是讀寫執行。
    -s檔案存在并且大小大于0為真。例子:[ -s file_path ]               

7.單小括号( )、雙小括号( )、單中括号[ ]、雙中括号及大括号{ }:

小括号( ):
    指令組:括号中的指令将會新開一個子shell順序執行,是以括号中的變量不能夠被腳本餘下的部分使用。括号中多個指令之間用分号隔開,最後一個指令可以沒有分号,各指令和括号之間不必有空格。
    指令替換:等同于`cmd`,shell掃描一遍指令行,發現了$(cmd)結構,便将$(cmd)中的cmd執行一次,得到其标準輸出,再将此輸出放到原來指令。有些shell不支援,如tcsh。
    初始化數組:如:array a1=(a b c d)。
    
雙小括号(( )):
    整數運算:例子:echo $((4+5))或echo $((16#5f))結果為95(16進位轉十進制)。
    重定義變量:a=4;((a++))可以a重定義為5。
    雙括号中的變量可以不使用$符号字首。括号内支援多個表達式用逗号分開。例子:for((i=1;i<10;i++))。
    
單中括号[ ]:
    條件判斷: [ condition ]。例子:[ $a == abc  ]
    在一個array 結構的上下文中,中括号用來引用數組中每個元素的編号。例子:a[1]

雙中括号[[ ]]:
    條件判斷,[[ ]] 結構比[ ]結構更加通用。
    
大括号{ }:
    大括号擴充:(通配(globbing))将對大括号中的檔案名做擴充。在大括号中,不允許有空白,除非這個空白被引用或轉義。例子:mkdir {a,b}或mkdir {a...d}。
    代碼塊,又被稱為内部組,這個結構事實上建立了一個匿名函數 。與小括号中的指令不同,大括号内的指令不會新開一個子shell運作,即腳本餘下部分仍可使用括号内變量。括号内的指令間用分号隔開,最後一個也必須有分号。{}的第一個指令和左括号之間必須要有一個空格。
    
    【幾種特殊的替換結構:${var:-string},${var:+string},${var:=string},${var:?string}】
    ${var:-string}:如果var為空或者未設定,傳回string,var不變
    ${var:+string}:如果var有值,傳回string,var不變
    ${var:=string}:如果var為空或者未設定,傳回string,且var=word
    ${var:?string}:如果變量var為空或者未設定,傳回string并退出shell,string沒有值則輸出:parameter null or not set,用于檢測var是否被正常指派。
    
     ${var#*pattern}:# 從左到右,删除字元串開頭至第一次出現的pattern部分 
     ${var##*pattern}:# 從左到右,删除字元串開頭至最後出現pattern部分
     ${var%pattern*}:# 從右到左,删除字元串結尾至第一次出現pattern的部分
     ${var%%pattern*}:# 從右到左,删除字元串結尾至最後一次出現pattern的部分               

${ }引用變量的進階用法:

(1)字元串處理:【隻有在pattern中使用了通配符才能有最長最短的比對,否則沒有最長最短比對之分,隻有完整比對。】
    【下面的隻是更改輸出的内容,而var原值并未修改。】
    var=abcdefgabcdefg
    ${var#*pattern}    # 從左到右,删除字元串開頭至第一次出現的pattern部分 
    ${var##*pattern}    # 從左到右,删除字元串開頭至最後出現pattern部分
    例子如下:
        [root@centos7 /data/shell]#var=abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var#d}     
        abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var#*d}    
        efgabcdefg
        [root@centos7 /data/shell]#echo ${var##*d}
        efg
    
    ${var%pattern*}    # 從右到左,删除字元串結尾至第一次出現pattern的部分
    ${var%%pattern*}   # 從右到左,删除字元串結尾至最後一次出現pattern的部分 
    例子如下:
        [root@centos7 /data/shell]#var=abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var%d}
        abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var%d*}
        abcdefgabc
        [root@centos7 /data/shell]#echo ${var%%d*}
        abc
        
    ${var/pattern/substr}    # 查找var存儲的字元串中,第一個被pattern比對到的字元替換為substr
    ${var//pattern/substr}   # 查找var存儲的字元串中,所有被pattern比對到的字元替換為substr
    ${var/#pattern/substr}   # 查找var存儲的字元串中,開頭被pattern比對到的字元替換為substr
    ${var/%pattern/substr}   # 查找var存儲的字元串中,結尾被pattern比對到的字元替換為substr
    例子如下:var=abcdefgabcdefg
        [root@centos7 /data/shell]#var=abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var/d/D}
        abcDefgabcdefg
        [root@centos7 /data/shell]#echo ${var//d/D}
        abcDefgabcDefg
        [root@centos7 /data/shell]#echo ${var/#a/A}
        Abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var/%g/G}
        abcdefgabcdefG
        
    ${var/pattern/}    # 查找var存儲的字元串中,删除第一次被pattern比對到的字元
    ${var//pattern/}   # 查找var存儲的字元串中,删除所有被pattern比對到的字元
    ${var/#pattern/}   # 查找var存儲的字元串中,删除開頭被pattern比對到的字元
    ${var/%pattern/}   # 查找var存儲的字元串中,删除結尾被pattern比對到的字元
    例子如下:var=abcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var/d/}
        abcefgabcdefg
        [root@centos7 /data/shell]#echo ${var//d/} 
        abcefgabcefg
        [root@centos7 /data/shell]#echo ${var/#a/}
        bcdefgabcdefg
        [root@centos7 /data/shell]#echo ${var/%g/}
        abcdefgabcdef
        
    ${var^^}    # 将var存儲的字元串中的所有小寫替換為大寫
    ${var,,}    # 将var存儲的字元串中的所有大寫替換為小寫,注意是英文逗号
    例子如下:
        [root@centos7 /data/shell]#echo $var
        abcdefgabcdefg
        [root@centos7 /data/shell]#varR=${var^^}
        [root@centos7 /data/shell]#echo $varR
        ABCDEFGABCDEFG
        [root@centos7 /data/shell]#echo ${varR,,}
        abcdefgabcdefg
  (2)字元串切片:【下面的隻是更改輸出的内容,而var原值并未修改。】
      ${#var}        # 引用字元串的長度
          [root@centos7 /data/shell]#var=abcde
        [root@centos7 /data/shell]#echo $var
        abcde
        [root@centos7 /data/shell]#echo ${#var}
        5
    ${var:offset}  # 從左到右,引用字元串從第offset(不包括offset)個字元開始到最後的部分
        [root@centos7 /data/shell]#echo $var
        abcde
        [root@centos7 /data/shell]#echo ${var:3}
        de
    ${var:offset:number}    # 從左到右,引用字元串從第offset(不包括offset)個字元開始,長度為number的部分
        [root@centos7 /data/shell]#echo $var    
        abcde
        [root@centos7 /data/shell]#echo ${var:1:2}
        bc
    ${var: -length}        # 取字元串最右側length個字元,注意-length前有一個空格
        [root@centos7 /data/shell]#echo $var      
        abcde
        [root@centos7 /data/shell]#echo ${var:-3} 
        abcde
        [root@centos7 /data/shell]#echo ${var: -3}
        cde
        [root@centos7 /data/shell]#echo ${var:}   
        -bash: ${var:}: bad substitution
        [root@centos7 /data/shell]#echo ${var::}

        [root@centos7 /data/shell]#echo ${var::5}
        abcde
    ${var: -length:number}  # 先從右到左取length個字元,在從前邊得到的字元中取長度為number的部分,同樣的注意length前的空格  
        [root@centos7 /data/shell]#echo $var      
        abcde
        [root@centos7 /data/shell]#echo ${var: -3:2}
        cd
        
 字元串變量指派:【下面隻有=才會有可能更改var的值,其餘的都不人更改var的值】
     ${var:-value}        # var為空或未設定,則傳回value;有值則傳回var的值
     ${var:+value}        # var為空或未設定,則傳回空值;有值則傳回value
     ${var:=value}        # var為空或未設定,則傳回value并指派給value;有值則傳回var的值
     ${var:?error_info}   # var為空或未設定,則傳回error_info的資訊;有值則傳回var的值
     以${var:=value}為例:
         [root@centos7 /data/shell]#var=old    #有值
        [root@centos7 /data/shell]#echo $var
        old
        [root@centos7 /data/shell]#echo ${var:=new}
        old
        [root@centos7 /data/shell]#unset var    #未設定
        [root@centos7 /data/shell]#echo $var

        [root@centos7 /data/shell]#echo ${var:=new}
        new
        [root@centos7 /data/shell]#echo $var
        new
        [root@centos7 /data/shell]#var=       #為空
        [root@centos7 /data/shell]#echo $var

        [root@centos7 /data/shell]#echo ${var:=new}
        new
        [root@centos7 /data/shell]#echo $var
        new
        
(3)變量間接引用:
    如果var1=var2,var2=value,直接用變量var1引用value,這叫做變量的間接引用。
    方法一:eval tmpvar=\$$var1 ;echo ${tmpvar}
    方法二:引用${!var1}   
    例子如下:
        [root@centos7 /data/shell]#var=old
        [root@centos7 /data/shell]#var1=var2
        [root@centos7 /data/shell]#var2=abc
        [root@centos7 /data/shell]#echo $var1
        var2
        [root@centos7 /data/shell]#echo $var2
        abc
        [root@centos7 /data/shell]#echo \$$var1
        $var2
        [root@centos7 /data/shell]#eval tmpvar=\$$var1;echo $tmpvar  #方法一
        abc
        [root@centos7 /data/shell]#echo $!var1
        var1
        [root@centos7 /data/shell]#echo ${!var1}   #方法二
        abc           

7.流程控制:

(1)if:
    基本文法:【if、[、condition、]之間要有空格】
        if [ conditon ];then
            執行xx程式
        fi
        或者
        if [ condition ]
        then
            執行xx程式
        fi
(2)case:
    基本文法:
        case $變量 in 
            "value1")
                執行xx程式
                ;;
            "value2")
                執行xxx程式
                ;;
            *)
                執行xxxx程式
                ;;
        esac
    1)case行尾必須為單詞“in”,每一個模式比對必須以右括号“)”結束。
    2)雙分号“;;”表示指令序列結束,相當于java中的break。
    3)最後的“*”表示預設模式,相當于java中的default。
(3)for:
    基本文法:
        形式一:
            for((初始值;循環控制條件;變量變化))
            do
                執行程式
            done
        形式二:
            for 變量 in value1 value2 value3...
            do
                執行程式
            done
       【$*與$@,都是代表全部元素,當加上雙引号後則不同:"$*"表示元素一次輸出; "$@"表示元素一個一個地輸出。
        以數組為例子:
            【當${var[*]}與${var[@]}不加雙引号時,輸出結果都為元素一個一個地輸出。當加上雙引号後則前者全部輸出,後者一個一個輸出】
            var=(a abc d e f 5)
            for i in "${var[*]}"     
            do
                    echo $i
            done
            #最終結果為a abc d e f 5
            
            echo “-===========”
            for i in "${var[@]}"
            do
                    echo $i
            done
            #最終結果為  a
                        abc
                        d
                        e
                        f
                        5
(4)while:
    基本文法:
        while [ condition ];do
            執行程式
        done
        或者
        while [ condition ]
        do
            執行程式
        done
        例子如下:
           sum=0
            i=1
            while [ $i -le 100 ]
            do
                    sum=$[$sum+$i]
                    i=$[$i+1]
            done
            echo $sum           

8.read讀取控制台輸入:

基本文法:
    read (選項) (參數)
    選項: 
        -p:指定讀取時的提示符;
        -t:指定讀取值時等待的時間(秒);時間一過就消失
    參數:
        變量:指定讀取值的變量名。
    例子:
        read -t 4 -p "please input something:" var;echo $var
               

9.函數:【函數也是指令,可以

或$()來引用 】

(1)系統函數:
    basename:【别看是路徑,其實是對字元串的操作】
        basename [string/pathname][suffix]則是删除所有的字首包括最後一個(‘/’)字元,然後将字元串顯示出來。選項suffix為字尾,如果suffix被指定了,basename會将pathname或string中的suffix去掉。
        Examples:
          basename /usr/bin/sort          -> "sort"
          basename include/stdio.h .h     -> "stdio"
          basename -s .h include/stdio.h  -> "stdio"
          basename -a any/str1 any/str2   -> "str1" followed by "str2"
    dirname:【别看是絕對路徑,其實是對字元串的操作】
        dirname 則是去掉最後一個非斜杠部分和尾部斜杠; 如果名稱中不包含 ‘/’,則輸出‘. ’(指工作目錄)。
        Examples:
          dirname /usr/bin/          -> "/usr"
          dirname dir1/str dir2/str  -> "dir1" followed by "dir2"
          dirname stdio.h            -> "."
        
(2)自定義函數:
    基本文法:
        [function]funname()
        {
            Action  #後面可以加上分号,也可以不加上分号
            [return int]  #int這個數字在0-255(包括0與255)
        }
        funname   #調用函數
    例子如下:
        [root@centos7 /data/shell]#cat function.sh 
            #!/bin/bash
            test()
            {
                    var=abc;
                    echo $var
                    return 144
            }
            test
            
            [root@centos7 /data/shell]#bash function.sh 
            abc
            [root@centos7 /data/shell]#echo $?
            144
    【函數的()不可少;先聲明函數,再調用函數,shell腳本是逐行運作的,不會像其它語言一樣先編譯。
      函數的傳回值隻能通過$?系統變量獲得,也可能通過return傳回。如果不加,将以最後一條指令運作結果作為傳回值。return後跟數值(0-255)
    】
    
    第二個例子:
        [root@centos7 /data/shell]#cat func2.sh    
        #!/bin/bash
        test()
        {
                sum=$[$1+$2]
                echo $sum
        }
        read -p "請輸入第一個數:" num1
        read -p "請輸入第二個數:" num2
        echo "這兩數的和:"`test $num1 $num2`   #函數也是指令,也可以echo "這兩數的和:"$(test $num1 $num2)           

10.shell工具:

(1)tr:translate的簡寫,主要用于壓縮重複字元,删除檔案中的控制字元以及進行字元轉換操作。
    基本文法:tr [OPTION]... SET1 [SET2]
    -s:squeeze-repleats壓縮重複字元。例如壓縮空格:echo "a b   c  e"|tr -s" ",結果為a b c e【壓縮是把連續相同的壓縮成一個】
    -d: delete删除字元。例如:echo "aabcc"|tr -d "b",結果為aacc。
    -t:truncate,将SET1中字元用SET2對應位置的字元進行替換,一般預設為-t。例如:echo "a b c"|tr -t " " ":" ,結果為a:b:c。
        也可以利用字元集合進行轉換: echo abcd|tr -t [:lower:] [:upper:] ,其結果為ABCD(小寫轉換成大寫)。
(2)cut:切割,從檔案的每一行剪切位元組、字元和字段并輸出。【隻能以指定數目的制表符進行切割,如空格,要确定空格的個數】
    基本文法:cut [選項參數] filename
        選項參數:-f為列号,提取第幾列;
                    例如: -f 1(某列)或-f 2,3(某幾列)戒-f 3-(數字後負号從第三列往後)或-f -3(數字前負号從第三列之前)
                -d為分隔符,按照指定分隔符分隔列;預設分隔符為制表符
(3)sort:排序
    基本文法:sort (選項)(參數)
    選項:-t指定排序時所用的分隔符;
         -k指定需要排序的列;
         -n依照數值的大小排序;
         -r以相反的順序來排序;
    參數:指定待排序的檔案清單。
    例子:sort -t : -nrk 2 xxx
    
(4)grep:用于查找檔案裡符合條件的字元串。
    基本文法:grep [選項參數] "match_pattern" filename 【match_pattern外的雙引号可無】
        選項參數:-v 輸出除之外的所有行,相反輸出
                -E=egrep 使用擴充正規表達式
                -o 隻輸出檔案中比對到的部分
                -n 輸出包含比對字元串的行數
                -r 遞歸搜尋
                -i 忽略大小寫
                -e 多個比對樣式
                -q 靜默
    在grep搜尋結果中包括或者排除指定檔案:
       #隻在目錄中所有的.php和.html檔案中遞歸搜尋字元"main()"
        grep "main()" . -r --include *.{php,html}
        #在搜尋結果中排除所有README檔案
        grep "main()" . -r --exclude "README"
        #在搜尋結果中排除filelist檔案清單裡的檔案
        grep "main()" . -r --exclude-from filelist
    
    列印出比對文本之前或者之後的行:
        #顯示比對某個結果之後的3行,使用 -A 選項:seq 10 | grep "5" -A 3
        #顯示比對某個結果之前的3行,使用 -B 選項:seq 10 | grep "5" -B 3
        #顯示比對某個結果的前三行和後三行,使用 -C 選項:seq 10 | grep "5" -C 3
        #如果比對結果有多個,會用“--”作為各比對結果之間的分隔符:echo -e "a\nb\nc\na\nb\nc" | grep a -A 1
(5)sed: 是一種流編輯器,一次處理一行内容。
    基本文法:sed [選項參數] 'command' filename
        選項參數:-n是靜默輸出;-e多個指令執行的時候;-i修改檔案内容;-r擴充正規表達式。
        指令功能:p是顯示,一般與-n配合使用隻顯示比對到的行。
                a是新增,a的後面可以接字元串,在下一行出現;'2a str'或'/str/a str2'
                d是删除;'/str/d或2d'
                s是替換;'s/str1/str2/g'
(6)awk: 文本分析工具,把檔案逐行的讀入,以空格為預設分隔符将每行切片,切開的部分再進行分析處理。
    基本文法:awk [選項參數] 'pattern1{action1} pattern2{action2} ...' filename
        選項參數:-F指定輸入檔案分隔符;-v指派一個使用者定義變量。
        pattern: 表示AWK在資料中查找的内容,就是模式比對。
        action:在找到比對的内容時,所執行的一系列指令。
    例子如下:
        awk -F: 'BEGIN{print "user===>""shell"} {print $1,$7} END{print "newuser","/bin/newshell"}' /etc/passwd
        awk -F: '/^root/{print $0 " "NR,NF}' /etc/passwd 結果為:root:x:0:0:root:/root:/bin/bash 1 7
        ifconfig ens33|awk  '/netmask/{print $2}'列印ip,預設是以空格分隔符