shell


 

1、shell簡介

       shell是一個命令解釋器,它在操作系統的最外層,負責直接與用戶對話,把用戶的輸入解釋給操作系統,並處理各種各樣的操作系統的輸出結果,輸出到屏幕返回給用戶。這種對話方式可以是交互的方式(從鍵盤輸入命令,可以立即得到shell的回應),或非交互(腳本)的方式。換句話說,Shell是一個命令行解釋器,它為用戶提供一個像Linux內核發送請求以便運行程序的界面系統級程序,用戶可以用Shell來啟動,掛起,停止甚至是編寫一些程序。

      Shell還是一個功能相當請打的編程語言,易編寫,易調試,靈活性較強。Shell是解釋執行的腳本語言,在Shell中可以直接調用Linux系統命令。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2、shell變量

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.1 什么是變量:變量就是用一個固定的字符串(也可能是字符、數字等組合)代替更多更復雜的內容,該內容可能還會包含變量、路徑、字符串等其他路徑。

                                   

2.2 變量分類:環境變量(全局變量)和普通變量(局部變量)

2.2.1 普通變量

      定義變量和打印變量示例:

       刪除變量:unset  變量名 

2.2.2自定義環境變量

        設置環境變量                   !!!環境變量名通常要大寫

        <== 查看環境變量set、env、declare

         刪除環境變量:unset  變量名

    (1)用戶環境 變量配置文件:/root/.bashrc

    (2)全局變量配置文件:/etc/profile

                        /etc/bashrc                      #<==推薦此文件優先設置

                   /etc/profile.d/

2.2.3設置登錄提示

 <==在/etc/motd   文件中加入提示語即可

2.2.4變量定義及變量輸出說明

       單引號:所見即所得。

  雙引號:弱引用,輸出所有內容,如果內容中有命令(要反引下)、變量、特殊字符要轉義。

       反引號:引用命令。

注意:這里僅為Linux  shell下的結論

示例:

[root@localhost ~]# echo 'today is date'          <==單引號,所見即所。

today is date
[root@localhost ~]# echo 'today is `date`'        <==單引號引起內容時,內部有命令通過反引號引起來也沒用。
today is `date`
[root@localhost ~]# echo "today is `date`"        <==用雙引號,內部有命令通過反引號引起來有用。
today is Fri Oct 27 17:49:44 CST 2017
[root@localhost ~]# echo "today is date"           <==雙引號,輸出說有。
today is date
[root@localhost ~]# echo today is $(date)          <==$()相當於 ` ` 。

today is Fri Oct 27 17:50:37 CST 2017。

2.2.5針對AWK調用shell變量,使用引號情況介紹

1、賦值不加引號

[root@localhost ~]# a=123                   <==定義變量a,並賦值123,沒加引號。

[root@localhost ~]# awk 'BEGIN {print "$a"}'         <==加雙引號引用$a,輸出本身。
$a
[root@localhost ~]# awk 'BEGIN {print $a}'          <==不加引號引用$a,輸出空。

[root@localhost ~]# awk 'BEGIN {print "'$a'"}'       <==給$a加單引號,再加雙引號,輸出結果。
123

2、賦值加單引號

[root@localhost ~]# a='666'                      <==定義變量a,並賦值666,加單引號。

[root@localhost ~]# awk 'BEGIN {print "$a"}'
$a
[root@localhost ~]# awk 'BEGIN {print $a}'

[root@localhost ~]# awk 'BEGIN {print "'$a'"}'
666
[root@localhost ~]# awk 'BEGIN {print '$a'}'          <==加單引號,輸出結果。
666

3、賦值加雙引號

[root@localhost ~]# a="666"                        <==定義變量a,賦值666,加雙引號。

[root@localhost ~]# awk 'BEGIN {print "$a"}'
$a
[root@localhost ~]# awk 'BEGIN {print $a}'

[root@localhost ~]# awk 'BEGIN {print '$a'}'          <==給$a加單引號,再加雙引號,輸出結果。
666
[root@localhost ~]# awk 'BEGIN {print "'$a'"}'

666

4、賦值加反引號

[root@localhost ~]# a=`pwd`
[root@localhost ~]# echo $a
/root
[root@localhost ~]# awk 'BEGIN {print $a}'

[root@localhost ~]# awk 'BEGIN {print "$a"}'
$a
[root@localhost ~]# awk 'BEGIN {print '$a'}'
awk: cmd. line:1: BEGIN {print /root}
awk: cmd. line:1: ^ unterminated regexp
awk: cmd. line:1: BEGIN {print /root}
awk: cmd. line:1: ^ unexpected newline or end of string
[root@localhost ~]# awk 'BEGIN {print "'$a'"}'
/root

結論:不管變量如何定義賦值,在AWK取用shell變量時,我們更喜歡先用echo加符號輸出變量,然后通過管道給awk,進而控制變量的輸出結果。舉例如下:

 

[root@localhost ~]# a="rookie"
[root@localhost ~]# echo $a | awk '{print $1}'
rookie
[root@localhost ~]# echo $a | awk '{print $0}'
rookie

 

2.2.6變量定義總結

(1)變量名為只能為字母、數字、下划線,只能以字母或下划線開頭。

(2)變量名定義要規范,並且見名知意。

(3)一般變量定義、賦值用雙引號,簡單連續字符可以不加引號。

(4)希望解析變量結果用反引號或$().

2.3  shell中特殊且重要的變量

2.3.1位置參數變量

  $0     獲取當前執行shell腳本的文件名。

  $n     獲取當前執行的shell腳本的第幾個參數,n=1....9,n>9時,用花括號括起來例:${10}

  $#     獲取當前執行shell腳本后面接的參數的總個數。

  $*      獲取當前shell腳本所有傳參的參數,不加引號和$@相同。

  $@    獲取當前shell腳本參數所有傳參的參數,不加引號和$*相同。例如:"$@" 相當於"$1" "$2"...           表示獨立字符串。當"$@"和"$*"都加引號時,兩者有區別,都不加,兩者無區別。

2.3.2 shell進程中特殊狀態變量

  $?     獲取執行上條指令的執行結果返回值(0為成功,非0失敗),用於判斷上條命令執行是否成功。常用命令

  $$     獲取當前執行的shell腳本的進程號(PID)。不常用

  $!       獲取上一個后台工作進程的進程號(PID)。不常用

  $_      獲取在此之前執行的命令或腳本最后一個參數。不常用

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、變量數值運算

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3.1算數運算符

  

  

雙小括號的使用方法

  

let 命令用法:

[root@localhost ~]# i=2
[root@localhost ~]# let i=i+8
[root@localhost ~]# echo $i
10

提示:let i=i+8等同於((i=i+8)),但后者效率更高。

expr命令用法:

[root@localhost ~]# expr 2+2        <==注意數字與符號間要有空格
2+2
[root@localhost ~]# expr 2 + 2
4
[root@localhost ~]# expr 2 - 2
0
[root@localhost ~]# expr 2 * 2             <==*要用 \ 轉義
expr: syntax error
[root@localhost ~]# expr 2 \* 2
4
[root@localhost ~]# expr 2 / 2
1

 bc命令用法:

[root@localhost ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1+2                                          <== 輸入后按回車
3
2*3
6

 例1:此方法效率低,不推薦使用

[root@localhost ~]# i=5
[root@localhost ~]# i=`echo $i+6 | bc`
[root@localhost ~]# echo $i
11

 AWK實現計算

[root@localhost ~]# echo "3.4 2.9" | awk '{print ($1-$2)}'
0.5
[root@localhost ~]# echo "3 9" | awk '{print ($1+6)}'
9
[root@localhost ~]# echo "334 21" | awk '{print ($1-300)/$2}'
1.61905
[root@localhost ~]# echo "334 21" | awk '{print ($1-300)*$2}'
714

declare(同typeset)命令用法

[root@localhost ~]# declare -i A=20 B=19    <== -i參數可以將變量定義為整形
[root@localhost ~]# A=A+B
[root@localhost ~]# echo $A
39

$[]符號運算

[root@localhost ~]# echo $i
10
[root@localhost ~]# echo $[2*3]
6
[root@localhost ~]# echo $[2**3]
8
[root@localhost ~]# echo $[2/3]
0
[root@localhost ~]# echo $[3/2]
1
[root@localhost ~]# echo $[3%2]
1
[root@localhost ~]# echo $[1%2]
1
[root@localhost ~]# echo $[3%5]
3

read命令 

語法格式:read [參數] [變量名]

常用參數: -p prompt  設置提示信息。

                -t  timeout  設置輸入等待時間,默認單位秒。

例:

[root@localhost ~]# read -p "please input one num:" num
please input one num:666
[root@localhost ~]# echo $num
666

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4 、shell腳本條件測試與比較

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4.1條件測試

  

注意事項:1、語法一中test命令和語法2中的[] 等價。語法3中[[]]為擴展test命令。語法4中()())常用於計算。

                   2、[[]]中可以使用通配符等進行模式匹配,這是其區別於其他語法。

                   3、&&、||、>、< 等操作符可以應用在[[]]中。

                         -a、-o、-gt、-lt、-eq、-ne、-ge、-le  代替以上操作符。

                   4、對於整數的關系運算,也可以用shell的算數運算符(())。

test<測試表達式>示例:

[root@localhost ~]# test -f file && echo true || echo false
true

[<測試表達式>] 示例:

[root@localhost ~]# [ -f /test/file1 ] && echo 1 || echo 0
0

[[<測試表達式>]] 示例:

[root@localhost ~]# [[ -f /test/file1 ]] && echo 1 || echo 0
0

4.2 文件測試

  

 這些操作符對於[[]] 、[] 、test的測試都是通用。

4.3 特殊條件測試

4.4 字符串測試表達式

4.4.1 字符串測試操作符

  

提示:1對於字符串測試,一定要將字符串加引號之后在比較。如[ -n "ahjhfhe" ].

           2、比價符號兩端一定要有空格。

            3、“!=”和‘=’可用於比較兩個字符串是否相同。

 

 4.5 整數二元比較操作符

  

4.6 邏輯操作符

  

4.7  測試表達總結

  

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5、if條件語句

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5.1、單分支結構
語法:
if 條件
     then
        命令序列
fi

if 條件;then
    命令序列
fi

復合命令:條件滿足時,執行若干個命令
使用{}或者()
書寫規則:
(list) 在子shell中執行命令列表
{ list} 在當前shell中執行命令列表,指令寫在一行{必須有空客,最后一個指令以;結束。
示例1:兩個整數比較大小
示例2:測試腳本執行者,若不是root用戶,給出提示后則退出。
退出 exit 1
思路:
1、使用系統環境變量做判斷 USER UID
2、使用命令結果做判斷
whoami、id -u
示例3:判斷系統內存剩余大小,低於200M郵件報警。

5.2、雙分支結構
語法:
if 條件
then
  命令1
else
命令2
fi
示例4:雙分支if條件語句整數比較大小
示例5:判斷腳本目錄是否存在,存在打印目錄存在信息,否則創建目錄。
示例6:判斷目標主機是否存活,顯示檢測結果
ping -c 3 -i 0.2 -W 3 192.168.1.111 &> /dev/null

檢測web服務器是否正常訪問,正常顯示檢測結果,異常重啟apache。


5.3.多分支結構
語法:

if 條件1
  then
   命令1
elif 條件2
  then
    命令2
else
  命令n
fi

判斷當前主機的CPU生產商,其信息在/proc/cpuinfo文件中vendor_id一行中。
如果其生產商為GenuineIntel,就顯示其為Intel公司;
如果其生產商為AuthenticAMD,就顯示其為AMD公司;
否則,就顯示無法識別;
vendor=`grep vendor_id /proc/cpuinfo |uniq |cut -d' ' -f2`


判斷分數范圍,分出優秀、良好、合格、不合格四檔
85-100 優秀--A [ $score -ge 85 -a $score -le 100 ]
70-84 良好--B [ $score -ge 70 -a $score -lt 85 ]
60-69 合格--C [ $score -ge 60 -a $score -lt 70 ]
60分以下不合格--D else

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6、case多分支
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
case “var” in
pattern1) list1;;
pattern2) list2;;
...
            *) listn;;
esac

示例1:根據用戶輸入,判斷出該字符是字母、數字或者其他字符
read -p "please input a character: " num
case "$num" in
[a-zA-Z])
          echo "$num is letter"
;;
[0-9])
          echo "Snum is digit"
;;
*)
           echo "Other!"
esac

示例2:將判斷分數范圍多分支語句用case語句實現

case語句編寫服務啟動腳本

系統示例腳本:

/etc/init.d/portmap


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7、循環
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7.1、while
當型循環

while condition
do
      list
done

循環語句:
1、變量初始值
2、變量增加
3、避免死循環

示例1:批量創建用戶
要求:
用戶名以test開頭,按數字序號變化;
一共添加30個賬號,即test01,test02…,test30
用戶初始密碼為123456

思路:
i=1
while [ $i -le 30 ]
do
      if [ $i -lt 10 ]
      then
           username=test0$i
      else
            username=test$i
      fi
useradd $username
echo "123456" | passwd --stdin $i
let i++
done
示例2:猜商品價格
         通過變量RANDOM獲得隨機數
         提示用戶猜測並記錄次數,猜中后退出循環

          price=`$[$RANDOM%1000]`
          times=0

#/bin/bash

# define var
PRICE=$[$RANDOM % 100]
TIMES=0

while true
do
              read -p "Please enter the product price [0-99] : " INT
              let TIMES++
              if [ $INT -eq $PRICE ]
              then
                        echo "Good luck,you guessed it."
                        echo "You have guessed $TIMES times."
                         exit 0
                elif [ $INT -gt $PRICE ]
                then
                          echo "$INT is too high"
                 else
                           echo "$INT is too low"
                     fi
done

 

while true
do
       list
done

示例3:while讀取文件
工作過程中遇到要從一個ip列表中獲取ip port,然后ssh ip 到目標機器進行特定的操作

 


while讀取文件方法:
方法1:文件描述法
exec < FILE
Sum=0
while read line
do
       cmd
done
方法2:重定向法
cat $FILE | while read line
do
       cmd
done
方法3:read釜底抽薪
while read line
do
         cmd
done < FILE

while read line
do
    IP=`echo $line | cut -d' '-f1`
    PORT=`echo $line | cut -d' ' -f2`
     echo "IP: $IP, PORT: $PORT"
done <ip.txt
另外逐行讀取文件效率最高為for循環
for line in $(cat $FILE)
do
      cmd
done

以上方法中for循環效率最高,read 釜底抽薪次之。

 

7.2、until


until condition
do
       list
done

7.3、for

1)列表for循環
語法:
for var in list
     do
          commands
     done
2)不帶列表for循環
語法:
for var
     do
          statements
     done
提示:不帶列表的,相當於in “$@”。


3)C風格for循環
語法:
for ((exp1;exp2;exp3))
     do
          statements
     done

示例1:直接列出變量列表所有元素

示例2:獲取當前目錄下的文件名作為變量列表打印輸出

示例3:將之前用while語句創建的test01-test30用戶刪除

示例4:MySQL分庫分表備份

示例5:不帶列表for循環



循環控制結構:
break
循環結構 for/while 中使用,中止循環,若 break 后面指定一個數值 n 的話,則"從里向外"打斷第 n 個循環,默認值為 break 1 ,也就是打斷當前的循環。

continue
在循環結構 for/while 中使用,提前結束本輪循環,continue 后面也可指定一個數值 n ,以決定繼續哪一層(從里向外計算)的循環,默認值為 continue 1 ,也就是繼續當前的循環

exit
exit命令用於退出當前shell,在shell腳本中可以終止當前腳本執行

退出碼(exit status,或exit code)的約定:
         0表示成功(Zero - Success)
         非0表示失敗(Non-Zero - Failure)
           2表示用法不當(Incorrect Usage)
    127表示命令沒有找到(Command Not Found)
      126表示不是可執行的(Not an executable)
            >=128 信號產生


7.4、select
select語句結構:

select 變量 in 選項1 選項2
do
         break
done

select 表達式是一種bash的擴展應用,動作包括:
自動用1,2,3,4列出菜單 (沒有echo指令,自動顯示菜單)
自動read輸入選擇 (沒有 read指令,自動輸入)
賦值給變量 (沒有賦值指令,自動輸入數字后,賦值字符串給變量)

select本身就是一個循環,break是當選擇后,就跳出循環

示例:
# vim 01.sh

#/bin/bash

echo "What is your favourite OS?"
select var in Linux Windows Mac other
do
       break
done


echo "You have selected $var"

# sh 01.sh
What is your favourite OS?
1) Linux
2) Windows
3) Mac
4) other
#? 2
You have selected Windows

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

8、函數

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
函數的作用就是把程序里多次調用的相同的代碼,定義為一份,然后起個名字,所有的調用都只用這個名字即可。修改代碼時,只需要改變函數體內的代碼即可。
優勢
1、 把相同的程序段定義為函數,可以減少程序代碼量;
2、 增加程序可讀,易讀性;
3、 實現程序的功能模塊化;

定義:

格式一:
function 函數名( )
{
       指令…
}

格式二:
函數名()
{
       指令…
}

格式三:
function 函數名
{
       指令…
}


函數結束狀態
             執行函數時,函數中最后一個命令的傳回值代表函數的結束狀態。也可以使用return自定義執行狀態返回值,遇到return命令就立即結束,回到調用函數下一個命令,此時函數傳回值0。

函數執行:

調用函數:
            直接執行函數名即可。
                    函數名
            帶參數的函數執行方法:
                      函數名 參數

示例1:
寫一個腳本,判定192.168.0.200-192.168.0.254之間的主機哪些在線。
要求:
1、使用函數來實現一台主機的判定過程;
2、在主程序中來調用此函數判定指定范圍內的所有主機的在線情況。
#直接使用函數實現(無參數,無返回值)
#使用函數傳參(有參數,無返回值)
#使用函數返回值判斷(有參數,有返回值)

示例2:寫一個腳本:使用函數完成
1、函數能夠接受一個參數,參數為用戶名;
判斷一個用戶是否存在
如果存在,就返回此用戶的shell和UID;並返回正常狀態值;
如果不存在,就說此用戶不存在;並返回錯誤狀態值;
2、在主程序中調用函數;


shell函數與變量作用范圍
變量作用范圍
沒有特別定義均為全局,局部變量使用local定義

移動位置參數shift n

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
9、數組
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

數組(也稱Shell數組變量) ---一組數據的集合
普通數組:只能使用整數作為數組下標(數組索引)
關聯數組:可以使用字符串作為數組下標(數組索引)



1、定義數組
數組名=(值1 值2 ... 值n)

示例:
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)

還可以單獨定義數組的各個部分
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用連續的下標,而且下標的范圍沒有限制。

2、數組操作

1)獲取數組長度
# 取得數組元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得數組單個元素的長度
lengthn=${#array_name[n]}

2)引用數組
${數組名[下標]}

3)遍歷數組
示例:
[root@localhost Scripts]# filename=(`ls`)
[root@localhost Scripts]# for var in ${filename[@]};do echo $var;done
或者
[root@localhost Scripts]# for var in ${filename[*]};do echo $var;done
或者
[root@localhost Scripts]# for ((i=0;i<${#filename[@]};i++));do echo ${filename[i]};done
4)數組的刪除
unset array[1] # 刪除數組中第一個元素
unset array # 刪除整個數組

示例:
1、從“標准輸入”讀入n次字符串,每次輸入的字符串保存在數組array里
i=0
n=5
while [ "$i" -lt $n ] ; do
  echo "Please input strings ... `expr $i + 1`"
  read array[$i]
  b=${array[$i]}
  echo "$b"
  i=`expr $i + 1`
done

2、將字符串里的字母逐個放入數組,並輸出到“標准輸出”
chars='abcdefghijklmnopqrstuvwxyz'
for (( i=0; i<${#chars}; i++ )) ; do
  array[$i]=${chars:$i:1}
  echo ${array[$i]}
done

${chars:$i:1},表示從chars字符串的 $i 位置開始,獲取 1 個字符

3、把1-3 3個數字存到數組里 分別乘以8 然后依次輸出。
#!/bin/bash

array1=(`seq 3`)

for ((i=0;i<${#array1[@]};i++))
do
          echo $[${array1[$i]}*8]
done
------------------------------------------------------------------------------
10、正則表達式
------------------------------------------------------------------------------
1、什么是正則表達式?
簡單的說,正則表達式就是一套處理大量的字符串而定義的規則和方法。
例如:假設 @代表12345
通過正則表達式這些特殊符號,我們可以快速過濾、替換需要的內容。

2、為什么要學習正則表達式?
在工作中,我們做linux運維工作,時刻面對着大量的日志,程序,命令的輸出。
迫切的需要過濾我們需要的一部分內容,甚至是一個字符串。

3、兩個注意事項:
1)正則表達式的應用非常廣泛,存在於各種語言中,比如PERL,PHP,JAVA等
我們主要學習linux的正則表達式,系統運維工作中常用的正則表達式
常用的正則表達式命令為grep(egerp),sed,awk。
linux三劍客,要想三劍客玩得更好,那就一定離不開正則表達式。

2)linux正則表達式和我們命令行中其他的命令使用的通配符是有本質區別的。

注意事項:
a、linux正則表達式一般是以行為單位處理。
b、alias grep='grep --color=auto',匹配到高亮顯示
c、注意字符集,LC_ALL=C
4、linux正則表達式

10.1 、基於grep來講。
基礎正則表達式:BRE(basic regular expression)
1)^word 表示搜索以word開頭的內容。
2)word$ 表示搜索以word結尾的內容。
3)^$ 表示空行,不是空格。
4). 代表且只能代表一個任意字符。
5)\ 轉義字符,讓有着特殊身份意義的字符。
例如:\.只表示小數點,還原原始的小數點的意義。
6)* 重復0個或多個前面的字符
7).* 匹配所有的字符。^.* 任意多個字符開頭。
8)[] 匹配字符集合內任意一個字符,如[a-z]
9)[^abc] ^在中括號里表示非,不包含a或b或c
10){n,m} 匹配n到m次,前一個字符。
{n,} 至少N次,多了不限。
{n} N次
{,m} 至多m次,少了不限。
注意:grep要{轉義},\{\},egrep不需要轉義
11)\<或\b:錨定詞首(支持vi和grep),其后面的任意字符必須作為單詞首部出現,如 \<love或\blove
12)\>或\b:錨定詞尾(支持vi和grep),其前面的任意字符必須作為單詞尾部出現,如 love\>或love\b

后項引用:后面例子中會用到。
分組:
\(\)
  \(ab\)*
  后項引用
  \1:引用第一個左括號以及與之對應的右括號所包括的所有內容
  \2:
  \3:


擴展正則表達式:
+    重復一個或者一個以上的前一個字符,如o+表示一個以上的o,。+ 等價於 {1,}。
?   0個或者1個前一個字符,如o?表示空白或者1個o,? 等價於 {0,1}。
|    或,如要查找gd或者good這兩個字符,egrep -n 'gd|good' grep.man,可以更多個字符串相或
()    找 組 字符串,如查找glad或者good, egrep -n 'g(la|oo)d' grep.man
()+    多個重復組的判別,如查找A開頭C結尾,中間有一個以上的xyz,egrep -n 'A(xyz)+C' grep.man

grep命令:
-v:排除匹配的內容
-E:支持擴展的正則表達式
-i:忽略大小寫
-o:只輸出匹配的內容
--color=auto 匹配的內容顯示顏色
-n 在行首顯示行號


示例:
1、顯示/proc/meminfo文件中以不區分大小的s開頭的行;
grep -i '^s' /proc/meminfo
或 grep '^[sS]' /proc/meminfo
2、顯示/etc/passwd中以nologin結尾的行;
grep 'nologin$' /etc/passwd
3、取出默認shell為/sbin/nologin的用戶列表
grep '/sbin/nologin$' /etc/passwd | cut -d: -f1
4、取出默認shell為bash,且其用戶ID號最小的用戶的用戶名
grep 'bash$' /etc/passwd | sort -n -t: -k3 | head -1 | cut -d: -f1
5、顯示/etc/inittab中以#開頭,且后面跟一個或多個空白字符,而后又跟了任意非空白字符的行;
grep '^#[[:space:]]\{1,\}[^[:space:]]' /etc/inittab
6、顯示/etc/inittab中包含了:一個數字:(即兩個冒號中間一個數字)的行;
grep ':[0-9]:' /etc/inittab
或 grep -o ':[[:digit:]]:' /etc/inittab
7、顯示/boot/grub/grub.conf文件中以一個或多個空白字符開頭的行;
grep '^[:space:]\{1,\}' /boot/grub/grub.conf
8、顯示/etc/inittab文件中以一個數字開頭並以一個與開頭數字相同的數字結尾的行;
grep '^\([0-9]\).*\1$' /etc/inittab
或 grep '^\([[:digit:]]\).*\1$' /etc/inittab
9、找出/proc/cpuinfo中的,1位數,或2位數;
grep '[0-9]\{1,2\}' /proc/cpuinfo
或 grep '[[:digit:]]\{1,2\}' /proc/cpuinfo


10、取出本機所有IP地址(不包括lo),並用如下格式打印
eno16777736: 192.168.95.120
eno33554984: 192.168.253.153
eno50332208: 10.20.0.128

方法一:
#!/bin/bash


Net_Name=(`ifconfig | grep -v "lo:" | egrep "^[[:alpha:]]{1,}" | cut -d' ' -f1`)
#Net_Name=(`ifconfig | awk '$1 !~ /lo/ && /^[[:alpha:]]{1,}/ {print $1}'`)


for var in ${Net_Name[@]}
do
echo -e "$var\t`ifconfig | grep -A 1 "$var" | grep "inet" |tr -s ' '|cut -d' ' -f3`"
#echo -e "$var\t`ifconfig | grep -A 1 "$var" | awk '/inet/ {print $2}'
done

方法二:
#!/bin/bash


Net_Name=(`ip a | egrep "^[0-9]{1,}" | grep -v "lo:"| cut -d' ' -f2`)
#Net_Name=(`ip a | awk '$2 !~ /lo/ && /^[0-9]{1,}/ {print $2}'`)


for var in ${Net_Name[@]}
do
  echo -e "$var\t`ip a | grep -A 2 "$var" | grep "inet" | tr -s ' ' | cut -d' ' -f3 | cut -d/ -f1`"
  #echo -e "$var\t`ip a | grep -A 2 "$var" | awk '/inet/ {print $2}' | awk -F/ '{print $1}''
done

方法三:

Net_Name=(`ifconfig | awk -F: '$1 !~ /lo/ && /^[[:alpha:]]+/ {print $1}'`)

for var in ${Net_Name[@]}
do
  echo -e "$var:\t`ifconfig $var | awk 'NR==2 {print $2}'`"
done

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM