1. 程式人生 > >shell基礎程式設計例項

shell基礎程式設計例項

shell  程式設計 例項

案例:

 

  1. 字串擷取  ?

使用 ${}  怎麼做 擷取?

[[email protected] ~]# SCHOOL="Tarena IT Group."

[[email protected] ~]# echo ${#SCHOOL}

16

[[email protected] ~]# echo ${SCHOOL::6}

Tarena

[[email protected] ~]# echo ${SCHOOL:0:6}

Tarena

[[email protected]

~]# echo ${SCHOOL:1:6}

arena

[[email protected] ~]#

 

使用expr substr  怎麼擷取?

[[email protected] ~]# SCHOOL="Tarena IT Group."

[[email protected] ~]# expr substr "$SCHOOL" 1 6    //必須加引號 注意

Tarena

 

使用 cut 工具 怎麼分隔?

[[email protected] ~]# SCHOOL="Tarena IT Group."

[[email protected] ~]# echo $SCHOOL | cut -b 1-6

Tarena

[[email protected] ~]# echo $SCHOOL | cut -b -6

Tarena

[[email protected] ~]# echo $SCHOOL | cut -b 8-

IT Group.

[[email protected] ~]# echo $SCHOOL | cut -b 9

T

 

字串怎麼 替換?

[[email protected] ~]# SCHOOL="Tarena IT Group."

[[email protected] ~]# echo ${SCHOOL/r/XXX}

TaXXXena IT Group.

[[email protected] ~]# echo ${SCHOOL//r/XXX}

TaXXXena IT GXXXoup.

[[email protected] ~]# echo ${SCHOOL/$SCHOOL/xxx}

xxx

 

字串怎麼匹配刪除 ?

[[email protected] ~]# echo $MAIL

/var/spool/mail/root

[[email protected] ~]# echo ${MAIL#*oo}

l/mail/root

[[email protected] ~]# echo ${MAIL##*oo}

t

[[email protected] ~]# echo ${MAIL##*/}

root

 

[[email protected] ~]# echo $MAIL

/var/spool/mail/root

[[email protected] ~]# echo ${MAIL%oo*}

/var/spool/mail/r

[[email protected] ~]# echo ${MAIL%%oo*}

/var/sp

 

批量修改當前目錄下的副檔名 將.doc 改為.txt?

 

[[email protected] ~]# more rename.sh

#!/bin/bash

for FILE in *.doc

do

    mv $FILE ${FILE%.doc}.txt

 

done

 

帶引數 $1, $2   如: ./rename.sh .txt .doc

[[email protected] ~]# more rename.sh

#!/bin/bash

for FILE in *"$1"

do

    mv $FILE ${FILE%$1}"$2"

 

done

 

:- 取值; :=  取值 加賦值  ?

[[email protected] ~]# echo $SCHOOL

Tarena IT Group

[[email protected] ~]# echo ${SCHOOL:-Tarena}

Tarena IT Group

[[email protected] ~]# echo $SCHOOL

Tarena IT Group

[[email protected] ~]# unset SCHOOL

[[email protected] ~]# echo ${SCHOOL:-Tarena}

Tarena

[[email protected] ~]# echo $SCHOOL

 

[[email protected] ~]#

//變數值不存在情況

[[email protected] ~]# echo $SCHOOL

 

[[email protected] ~]# echo ${SCHOOL:=Tarean}

Tarean

[[email protected] ~]# echo $SCHOOL

Tarean

 

//變數值存在的情況

[[email protected] ~]# echo $SCHOOL

Tarean

[[email protected] ~]# echo ${SCHOOL:=Tarena IT Group.}

Tarean

[[email protected] ~]# echo $SCHOOL

Tarean

 

從鍵盤讀入一個正整數x, 求從 1到 x 的和; 當用戶未輸入值時, 為了避免出錯,x賦初值1.  ?

[[email protected] ~]# more sumx.sh

#!/bin/bash

read -p "請輸入一個正整數:" x

 

x=${x:-1}

i=1; SUM=0

while [ $i -le $x ]

do

    let SUM+=i

    let i++

done

 

echo "從1到$x的總和是:$SUM"

 

怎麼 運算 預設 1+2 中 1,2 是被當為字串的  怎麼 加減乘除運算 ?

 

[[email protected] ~]# A=1+2

[[email protected] ~]# echo $A

1+2

[[email protected] ~]# X=24

[[email protected] ~]# A=$X+2

[[email protected] ~]# echo $A

24+2

 

[[email protected] ~]# declare -i A

[[email protected] ~]# A=1+2

[[email protected] ~]# echo $A

3

[[email protected] ~]# declare -i B=$X+2

[[email protected] ~]# echo $B;

26

 

//declare -x  可以將區域性變數設定為全域性變數

//  -r  是隻讀

 

怎麼定義陣列, 怎麼獲取元素, 總數等 ?

 

[[email protected] ~]# MY_SVRS=(www ftp mail club)

[[email protected] ~]# echo ${MY_SVRS[@]}

www ftp mail club

[[email protected] ~]# echo ${MY_SVRS}

www

[[email protected] ~]# echo ${MY_SVRS[0]}

www

[[email protected] ~]# echo ${MY_SVRS[@]:1:2}

ftp mail

[[email protected] ~]# echo ${#MY_SVRS[@]}

4

 

 

怎麼 實現 ssh 自動登入指令碼 ,主要用到了什麼功能?

[[email protected] ~]# more ./expect_ssh.sh

#!/usr/bin/expect



set host 192.168.3.154

set user root

set password "123qwe"



spawn  ssh  [email protected]$host



expect {

"yes/no"        {send "yes\r";exp_continue}

"password"      {send "123qwe\r"}

}



expect "\[$user\@" { send "pwd >> /tmp/$user.txt; exit\r" }

interact


使用正則表示式 :

[[email protected] ~]# grep '^root|^daemon' /etc/passwd

[[email protected] ~]# grep '^root\|^daemon'  /etc/passwd

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

daemon:x:2:2:daemon:/sbin:/sbin/nologin

[[email protected] ~]# grep -E '^root|^daemon' /etc/passwd

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

daemon:x:2:2:daemon:/sbin:/sbin/nologin

[[email protected] ~]# egrep '^root|^daemon' /etc/passwd

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

daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

我 只是想判斷是否也有複合正則 ,不需要輸出 怎麼做?

使用 -q ; quiet 靜默

[[email protected] ~]# grep -q '^192.168' /etc/hosts && echo "yes" || echo "no"

 

怎麼輸出匹配到的行數?

[[email protected] ~]# egrep -c '/sbin/nologin$' /etc/passwd

31

[[email protected] ~]# egrep '/sbin/nologin$'  /etc/passwd | wc -l

31

 

 

怎麼匹配 某個單詞?怎麼匹配以ll結尾的單詞的行 ?

[[email protected] ~]# egrep '\binit\b' /etc/rc.local

[[email protected] ~]# egrep '\<init\>' /etc/rc.local

 

 

[[email protected] ~]# egrep 'll\>' /etc/rc.local

[[email protected] ~]# egrep 'll\b' /etc/rc.local

 

匹配MAC地址 正則?

  1. [0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}

 

郵箱正則?

  1. [0-9a-zA-Z_.]{3,}@[0-9a-zA-Z.-]{2,}(\.[0-9a-zA-Z-]{2,})+

 

IP地址正則?

  1. \<[0-9]{1,3}(\.[0-9]{1,3}){3}\>

 

 

sed 命令 例項:

 

輸出 檔案第一行?

[[email protected] ~]# sed -n '1p'  /etc/passwd

 

刪除  檔案 1-4行文字  ?

[[email protected] ~]# sed '1,4d'  rc.local

//注意不用加 -n

 

直接 刪除原檔案 1-4行 文字。?

使用 -i 選項

[[email protected] ~]# sed -i  '1,4d' rc.local

 

怎麼指定多個編輯指令?比如  輸出 第一行,第四行內容?

使用  -e    或  ;  (分號)

[[email protected] ~]# sed  -n  -e '1p' -e '4p'  rc.local

 

[[email protected] ~]# sed -n '1p;4p'  rc.local

 

[[email protected] ~]# sed -n '{1p;4p}'  rc.local

 

輸出所有行,?相當於 cat命令

[[email protected] ~]# sed -n 'p'  rclocal.txt

 

輸出第 2行及 之後的3行?

[[email protected] ~]# sed -n '2,+3p'  rclocal.txt

 

輸出以 xxx (local) 結尾的 行 ?

[[email protected] ~]# sed -n  '/local$/p' rclocal.txt

 

輸出奇數行?

[[email protected] ~]# sed  -n 'p;n' rclocal.txt

 

輸出偶數行?

[[email protected] ~]# sed -n 'n;p'  rclocal.txt

 

輸出最後一行?

[[email protected] ~]# sed -n '$p' rclocal.txt

 

輸出檔案的 總的行數?

[[email protected] ~]# sed -n '$='  rclocal.txt

 

刪除 包含 init  ,  bin的行 ?

[[email protected] ~]# sed '/init/d;/bin/d'  rclocal.txt

 

刪除  不包含init 的行  刪除  ?

!d

[[email protected] ~]# sed  '/init/ !d'  rclocal.txt

p

[[email protected] ~]# sed -n '/init/p'  rclocal.txt

 

刪除所有空行  ?

^$

[[email protected] ~]# sed  '/^$/d'   rclocal.txt

 

替換 s

將 所有行   第一個ll  替換為  “XX”  ?

[[email protected] ~]# sed 's/ll/XX/'  rclocal.txt

 

將 所有行 中 所有 ll  替換為  “XX” ?

[[email protected] ~]# sed  's/ll/XX/g'  rclocal.txt

 

將第3行內 的 第2個 “script”  替換為  “XX” ?

[[email protected] ~]# sed '3s/script/XX/2'  rclocal.txt

 

刪除 指定的字串 ?

替換為空

[[email protected] ~]# sed 's/init//g' rclocal.txt

 

刪除所有的“script”  “stuff”  字母 “e”   ?

或的關係 要用 \|  來表示

[[email protected] ~]# sed 's/script\|stuff\|e//g' rclocal.txt

 

去掉3-5 行的註釋?

[[email protected] ~]# sed  '3,5s/^#//'  rclocal.txt

 

將 /etc/rc.local 檔案 的第 6-7行 註釋掉 ?

行首新增 #

[[email protected] ~]# sed '6,7s/^/#/'  rclocal.txt

 

將 檔案每行 第1 個字元, 第二個字元交換?

-r  啟用正則擴充套件  \2  引用第二個()匹配到的。

[[email protected] ~]# sed -r 's/^(.)(.)/\2\1/' rclocal.txt

 

刪除行首 空格 ?

[[email protected] ~]# sed -r 's/^( )+//'  rclocal.txt

 

為檔案中每個大些字母新增 括號?

&  代表 匹配到的 整個字串

[[email protected] ~]# sed  's/[A-Z]/(&)/g' rclocal.txt

[[email protected] ~]# sed -r 's/([A-Z])/(\1)/g' rclocal.txt

 

 

對網絡卡 配置檔案 eth0 的修改 :

將IP地址 192.168.3.135 修改為   192.168.3.136 ?

思路 首先 定位到 IPADDR (正則定位)

[[email protected] ~]# sed -i '/IPADDR/s/192.168.3.29/192.168.3.136/'  /etc/sysconfig/network-scripts/ifcfg-eth0

 

sed 的多行操作:

c : 替換指定的行

i  :在指定的行之前插入文字

a  :  在指定的行 後追加 文字

 

sed 怎麼整行替換呢:?

修改主機名 ?

c  : 替換 指定的行

[[email protected] ~]# sed -i  '/^HOSTNAME/cHOSTNAME=liang'  /etc/sysconfig/network

 

在 hosts 檔案中, 新增兩行記錄 (a追加)

[[email protected] ~]# sed -i  '$a192.168.3.200 liang1.com\

> 192.168.3.202 liang2.com'  /etc/hosts

 

綜合案例:

找到 使用bash 登入 shell  的本地使用者;  按每行 使用者名稱—》  密碼  儲存到檔案a.log中 ?
 

#!/bin/bash

> /tmp/getupwd.log   ##建立空檔案

sed -n '/:\/bin\/bash$/w /tmp/user.tmp' /etc/passwd ##提取符合條件的帳號記錄

UNUM=$(egrep -c '.' /tmp/user.tmp)    ##取得記錄個數

#echo $UNUM



while [ ${i:=1} -le $UNUM  ]



do

    UREC=$(sed -n "${i}p" /tmp/user.tmp)

    #echo $UREC

    NAME=${UREC%%:*}        ##擷取使用者名稱:記錄去尾



    PREC=$(sed -n "/^$NAME:/p" /etc/shadow) ##查詢與使用者名稱對應的密碼記錄

    PASS=${PREC#*:}            ##掐頭

    PASS=${PASS%%:*}          ##去尾



    echo "$NAME--> $PASS" >> /tmp/getupwd.log   ##儲存結果



    let i++

done



/bin/rm -rf /tmp/user.tmp

echo "使用者分析完畢,請檢視檔案/tmp/getupwd.log"

二:使用awk 的方案

#!/bin/bash

> /tmp/getupwd.log

awk -F: '/:\/bin\/bash$/{print $1}' /etc/passwd > /tmp/user.tmp  ##提取使用者名稱



for NAME in $(cat /tmp/user.tmp)

do

    #grep "^$NAME:" i /etc/shadow | awk -F: '{print $1 "--->" $2}' /etc/shadow

    #echo $NAME

    grep "^$NAME:" /etc/shadow | awk -F: '{print $1 "--->" $2 | "cat >>/tmp/getupwd.log"}'

done

echo "使用者分析完畢,請檢視/tmp/getupwd.log"

/bin/rm -rf /tmp/user.tmp

 

參考 tts-shell  day05練習。

 

awk 例項:

 

awk  是 怎麼指定分隔符 呢?

預設是:不指定 就是 空格 或 製表符 做分隔;

[[email protected] ~]# awk -F:  '{print $1","$7}'  /etc/passwd

[[email protected] ~]# awk -F":" '{print $1","$7}' /etc/passwd

 

awk 怎麼指定多個分隔符呢?

[[email protected] ~]# awk -F [:/]  '{print $1,$10}' /etc/passwd

 

 

awk 有哪些內建的變數 ? 當前行號,列數  檔名?

[[email protected] ~]# awk '{print FILENAME,NR}' /etc/passwd

[[email protected] ~]# awk -F[:/] '{print NR,NF}' /etc/passwd

 

awk  怎麼使用環境變數?   輸出當前使用者的passwd的記錄?

[[email protected] ~]# awk -F: '$1==ENVIRON["USER"]{print $0}' /etc/passwd

 

統計使用bash 作為登入shell 的使用者總個數?

思路: 在begin 定義 計數變數 ; \< bash 匹配bash

[[email protected] ~]# awk 'BEGIN{x=0}/\<bash$/{x++}END{print x}' /etc/passwd

[[email protected] ~]# egrep -c '\<bash$' /etc/passwd

 

從ifconfig eth0  提取IP地址?

[[email protected] ~]# ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | awk -F: '{print $2}'

 

根分割槽 使用率?

[[email protected] ~]# df -hT / | tail -1 | awk '{print $5}'

 

 

分析/etc/passwd 檔案  輸出 列表頭; 使用者資訊,bash資訊,, 尾部:行數, 統計資訊。

[[email protected] ~]# awk -F: 'BEGIN{print "User\tUID\tHome"} \

> {print $1"\t"$3"\t"$6} END{print "Total "NR" lines."}' /etc/passwd

 

輸出 其中登入shell 不以nologin結尾 的使用者名稱,登入shell資訊?

第七個欄位 !~ 反向匹配

[[email protected] ~]# awk -F: '$7!~/nologin$/{print $1, $7}' /etc/passwd

 

 

輸出第3行的使用者記錄?

NR ==3

[[email protected] ~]# awk -F: 'NR==3{print}' /etc/passwd

輸出奇數行的使用者記錄?

[[email protected] ~]# awk -F: 'NR%2==1{print}' /etc/passwd

 

輸出偶數行的使用者記錄?

[[email protected] ~]# awk -F: 'NR%2==0{print}' /etc/passwd

 

輸出前3行使用者記錄?

[[email protected] ~]# awk -F: 'NR<=3{print}' /etc/passwd

 

輸出第3-5 行 使用者記錄?

[[email protected] ~]# awk -F: 'NR>=3 && NR<=5{print}' /etc/passwd

 

輸出 登入shell 不以nologin 結尾 或者 使用者名稱 以 a 或d 開頭 的文字 ?

[[email protected] ~]# awk -F: '$7!~/nologin$/||$1~/^[ad]/{print}' /etc/passwd

 

 

統計檔案中 欄位個數  ?

[[email protected] ~]# awk -F: 'BEGIN{x=0}{x+=NF}END{print "Total "x" fields."}' /etc/passwd

 

列出100以內 整數中7的倍數 或是含7的數?

[[email protected] ~]# seq 100 | awk '$0%7==0||$0~/7/{print}'

 

 

awk 流程控制考察。

 

統計/etc/passwd 檔案中登入shell不是“/bin/bash” 的使用者個數:?

單分支

[[email protected] ~]# awk -F: 'BEGIN{i=0}{if($7!~/bash$/){i++}}END{print i}' /etc/passwd

 

統計  /etc/passwd 檔案中UID 小於或等於500, UID 大於500的使用者個數:?

雙分支

[[email protected] ~]# awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}'  /etc/passwd

 

統計 /etc/passwd 檔案中登入shell 是 /bin/bash   sbin/nologin ,其他使用者 的個數 ?

[[email protected] ~]# awk -F: 'BEGIN{i=0;j=0;k=0}{if($7~/bash$/){i++}else if($7~/nologin$/){j++}else{k++}}END{print i,j,k}' /etc/passwd

 

統計 /etc/passwd 檔案內 root  出現的次數  ?

[[email protected] ~]# awk -F [:/] 'BEGIN{j=0}{i=1}{while(i<=NF){if($i~/root/){j++} i++}}END{print j}' /etc/passwd

 

[[email protected] ~]# echo $(cat /etc/passwd) | awk -F "root" '{print NF-1}'

 

計算從1-100內各整數的總和 ?

 

[[email protected] ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum += i} print sum}'

 

[[email protected] ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum += i; if(i==100){print sum}}}'

 

[[email protected] ~]# awk 'BEGIN{for(i=1;i<=100;i++){sum +=i;}}{}END{print sum}' /etc/passwd

 

 

跳過 當前 行 ?

next

[[email protected] ~]# awk 'NF<=2{next}{print}' /etc/rc.local

 

 

去處重複的行?

[[email protected] ~]# awk '!a[$0]++' a1.txt

 

[[email protected] ~]# awk '!a[$0]++{print $0}' a1.txt

 

統計web 訪問日誌 /var/log/httpd/access_log  統計IP 訪問量 ; 按訪問量排序?

sort ;  //-n 按數字排序 -r反序 ;-k2 按第二列排序

[[email protected] ~]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' access.log

 

[[email protected] ~]# awk '{ip[$1]++}END{for(i in ip){print i, ip[i]}}' access.log | sort -nr -k2

 

 

參考 tts-shell  day06練習。