1. 程式人生 > >SHELL指令碼------基礎知識(||)

SHELL指令碼------基礎知識(||)

一、Sed 行編輯器

一、sed:

1.用來操作純 ASCII 碼的文字
2.Sed 一次處理一行內容,處理時,把當前處理的行儲存在臨時緩衝區中,稱之為“模式空間”
3.可以指定僅僅處理哪些行,Sed 符合模式條件的處理,不符合條件的不予處理
4.處理完成之後把緩衝區的內容送往螢幕
5.接著處理下一行,這樣不斷重複,直到檔案末尾
二、sed命令格式
sed [引數] ‘命令’ file

三、sed 對字元的處理

p    顯示,    將某個選擇的資料列印顯示。通常p會與引數 sed -n 一起執行

d    刪除, 顯示模式空間刪除指定行後的內容,不會對原檔案資料刪除

a    新增, a的後面可以接字串,該字串會在當前指定行的下一行出現
c    替換,    c的後面可以接字串,該字串可以取代 n1,n2 之間的行
 i    插入,    i的後面可以接字串,該字串會在當前指定行的上一行出現 

p:

[[email protected] mnt]# cat -n /etc/fstab 
     1	
     2	#
     3	# /etc/fstab
     4	# Created by anaconda on Wed May  7 01:22:57 2014
     5	#
     6	# Accessible filesystems, by reference, are maintained under '/dev/disk'
     7	# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
     8	#
     9	UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 /                       xfs     defaults        1 1
[
[email protected]
mnt]# sed -n '/\:/p' /etc/fstab 顯示含有 : 的行 需要轉譯 # Created by anaconda on Wed May 7 01:22:57 2014 [[email protected] mnt]# sed -n '/^#/p' /etc/fstab 顯示以#號開頭的行 # # /etc/fstab # Created by anaconda on Wed May 7 01:22:57 2014 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # [
[email protected]
mnt]# sed -n '/^#/!p' /etc/fstab 顯示不是#號開頭的行 UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1 [[email protected] mnt]# sed -n '2,6p' /etc/fstab 顯示第2--6行 # # /etc/fstab # Created by anaconda on Wed May 7 01:22:57 2014 # # Accessible filesystems, by reference, are maintained under '/dev/disk' [[email protected] mnt]# sed -n '2,6!p' /etc/fstab 不顯示2--6行 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 / xfs defaults 1 1 [[email protected] mnt]# sed -n '2p;6p' /etc/fstab 顯示第二行和第六行 # # Accessible filesystems, by reference, are maintained under '/dev/disk'

d:

[[email protected] mnt]# sed '/^UUID/d' /etc/fstab        刪除以UUID開頭的行

#
# /etc/fstab
# Created by anaconda on Wed May  7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
[[email protected] mnt]# sed '/^#/d' /etc/fstab           刪除以#號開頭的行

UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 /                       xfs     defaults        1 1
[[email protected] mnt]# sed '/^$/d' /etc/fstab           刪除空行
#
# /etc/fstab
# Created by anaconda on Wed May  7 01:22:57 2014
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 /                       xfs     defaults        1 1
[[email protected] mnt]# sed '1,4d' /etc/fstab            刪除1--4行
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=9bf6b9f7-92ad-441b-848e-0257cbb883d1 /                       xfs     defaults        1 1

a:

[[email protected] mnt]# cat hello.sh 
hello
[[email protected] mnt]# sed '/hello/aworld' hello.sh 
hello
world
[[email protected] mnt]# sed 's/hello/hello world/g' hello.sh 
hello world
[[email protected] mnt]# sed 's/hello/hello\nworld/g' hello.sh 
hello
world

c:

i:

-i:  改變原檔案內容
sed -i 's/westos/redhat/' passwd

sed -i 's/westos/redhat/g' passwd    全域性替換

 

練習:

將httpd服務的埠80改為8080

#!/bin/bash

yum install -y httpd &> /dev/null
sed -i "/^Listen/cListen $1" /etc/httpd/conf/httpd.conf
echo -e "Port has changed!"
echo "Now ,Port is $1!"
systemctl restart httpd

二、 awk 簡介

1.Awk 是被設計用於文字處理,並通常被用作資料提取和報告工具的解釋性程式設計語言

2.目前在Linux中常用的是 awk 編譯版本有 mawk 、gawk

3.以 RedHat 為代表使用的是 gawk,以Ubuntu為代表使用的是 mawk

一、awk處理機制:

根據模式一次從檔案中抽取一行文字,對這行文字進行切片(預設使用空白字元作為分隔符)

[[email protected] mnt]# cat test
this  | is | a | file
 $1     $2   $3   $4
[[email protected] mnt]# awk '{print $0}' test
this   is  a  file
[[email protected] mnt]# awk '{print $1}' test
this
[[email protected] mnt]# awk '{print $2}' test
is
[[email protected] mnt]# awk '{print $3}' test
a
[[email protected] mnt]# awk '{print $4}' test
file
[[email protected] mnt]# awk '{print $1$2}' test
thisis

以:為分隔符,列印檔案/etc/passwd的第一列和第三列

二、awk的常用變數

1.輸出檔名,和當前操作的行號

2.輸出每次處理的行號,以及當前以":"為分隔符的欄位個數

3.輸出檔案/etc/passwd以/bash結尾的行

[[email protected] mnt]# awk -F: '/bash$/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
student:x:1000:1000:Student User:/home/student:/bin/bash

4.輸出/etc/passwd的第三行

[[email protected] mnt]# awk -F: 'NR==3 {print}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin

5.輸出/etc/passwd的偶數行

6.輸出/etc/passwd的第三行到第五行

[[email protected] mnt]# awk -F: 'NR >=3 && NR <=5 {print}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

7.輸出/etc/passwd下uid小於等於2的使用者名稱和uid

[[email protected] mnt]# awk -F: '$3 >=0 && $3 <=2 {print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2

四、Awk 的兩個特殊模式(BEGIN 和 END)

1.BEGIN 和 END,BEGIN 被放置在沒有讀取任何資料之前,而 END 被放置在所有的資料讀取完成以後執行

BEGIN{}: 讀入第一行文字之前執行的語句,一般用來初始化操作
{}: 逐行處理
END{}: 處理完最後以行文字後執行,一般用來處理輸出結果

舉例:

1.檔案開頭加REDHAT,末尾加WESTOS,列印行號和內容

 

2.統計文字總欄位個數

[[email protected] mnt]# cat test
hello hello xx
xx
xx  westos Xx
[[email protected] mnt]# awk 'BEGIN{i=0}{i+=NF}END{print i}' test
7

3.計算

[[email protected] mnt]# awk 'BEGIN { a=34;print a+10 }'
44

五、awk高階應用

1. if單分支語句

統計登入shell為bash的使用者

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

統計/etc/passwd下uid小於500的使用者個數

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

2. if雙分支語句

統計uid小於等於500和大於500的使用者個數

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

3. for迴圈

生成1-5序列  seq命令可直接生成

[[email protected] mnt]# awk 'BEGIN{for(i=1;i<=5;i++){print i}}'
1
2
3
4
5
[[email protected] mnt]# seq 5
1
2
3
4
5

4.while迴圈

[[email protected] mnt]# awk 'i=1 {} BEGIN {while (i<3) {++i;print i}}' test
1
2
3
[[email protected] mnt]# awk 'BEGIN {do {++i;print i} while (i<3)}' test
1
2
3

三、shell中的條件語句與迴圈語句(if ,for,while)

一、 if語句

if.sh

#!/bin/bash
user=kiosk
if grep $user /etc/passwd;then
    echo "Hello $user"
fi

if date;then
    echo "Hello date"
fi

if-else.sh

#!/bin/bash
user=student
if grep $user /etc/passwd;then
    echo "The files for user $user are:"
    ls -a /home/$user
else
    echo "$user not exist!"
fi

if-elif-else.sh

#!/bin/bash

if [ "$1" == "student" ];then
    echo "Welcome $1"
elif [ "$1" == "westos" ];then
    echo "Welcome $1"
elif [ "$1" == "kiosk" ];then
    echo "Welcome $1"
elif [ "$1" == "linux" ];then
    echo "Welcome $1"
else
    echo "You are not allowed!"
fi

二、 for迴圈

以指令碼方式生成1-5序列。

[[email protected] mnt]# cat 1.sh 
#!/bin/bash
for NUM in `seq 5`
do
    echo $NUM
done
[[email protected] mnt]# sh 1.sh 
1
2
3
4
5
[[email protected] mnt]# vim 2.sh
[[email protected] mnt]# cat 2.sh 
#!/bin/bash
for ((A=1;A<=5;A++))
do
    echo $A
done
[[email protected] mnt]# sh 2.sh 
1
2
3
4
5

生成奇數序列

[[email protected] mnt]# cat 3.sh 
#!/bin/bash
for NUM in `seq 1 2 10`
do
    echo $NUM
done
[[email protected] mnt]# sh 3.sh 
1
3
5
7
9
  • 練習:
1.檢測多臺主機的網路
#!/bin/bash

#for((a=1;a<70;a++))
#for a in `seq 60`
for a in {1..60}
do
    ping -c1 -w1 172.25.254.$a &> /dev/null && echo 172.25.254.$a is up || echo 172.25.254.$a is down
done

2.倒計時10秒

[[email protected] mnt]# cat time.sh
#!/bin/bash
for ((a=10;a>0;a--))
do
    echo -n " TIME $a"
    echo -ne "\r"
    sleep 1
done

3.客戶端輸入分和秒,開始倒計時

[[email protected] mnt]# cat time1.sh
#!/bin/bash
read -p "請輸入時間分秒:" a b
for ((c=(a*60)+b;c>0;c--))
do
   d=$[c/60]
   e=$[c%60]
   echo -n " TIME $d:$e "
   echo -ne "\r"
   sleep 1
done

三、while迴圈

建立使用者westos{1…20},並修改密碼為123456

[[email protected] mnt]# vim while.sh

刪除使用者westos{1..20}.

四、巢狀迴圈

[[email protected] home]# vim qt.sh

二、練習,生成9*9乘法表

[[email protected] home]# vim 99.sh

五、case語句

語句的書寫格式:

#!/bin/bash
case $1 in
student|kiosk|linux|westos)
     echo "Welcome,$1"
     ;;
*)
     echo "Sorry!"
     ;;
esac

2.練習:

書寫指令碼:

提示:\033[31m A \033[0m 輸出A則為紅色(32m—綠色33m—黃色34m—藍色

執行指令碼結果如下: