shell實例100例《八》

7一、題目要求  :  判斷文件並計算單詞java

【核心要點】

一、[ -f file ] 判斷否有某個文件mysql

二、grep -cw 獲取單詞個數linux

題目要求

  1. 判斷所給目錄內哪些二級目錄下有沒有text.txt文件。
  2. text.txt文件的二級目錄,計算出該test.txt文件裏面所給出單詞的次數。
  3. 假如腳本名字爲1.sh, 運行腳本的格式爲 ./1.sh 123 root,其中123爲目錄名字,而root爲要計算數量的單詞。

參考答案

#!/bin/bash
#這個腳本用來判斷文件是否存在並計算單詞個數
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-11

if [ $# -ne 2 ]
then
    echo "請提供兩個參數,第一個參數是目錄名字,第二個參數是單詞"
    exit
fi

cd $1
for f in `ls .`
do
    if [ -d $f ]
    then
	if [ -f $f/test.txt ]
	then
	    n=`grep -cw "$2" $f/test.txt`
	    echo  "$1/$f目錄下面有test.txt, 該test.txt裏面的有$n個$2."
	fi
    fi
done

實例 :git

執行腳本,查看結果github

注意  : 算法

判斷一個目錄下,有有沒有文件,使用-f test.txtsql

if [ $# -ne 2 ]                    #若是不等於2shell

cd $1                           #    切換到所給目錄下數據庫

if [ -f $f/test.txt ]                        #判斷目錄下面有沒有test.txt文件tomcat

n=`grep -cw "$2" $f/test.txt`                      #查找$2在/test.txt出現的次數  -c:計算次數;-w :做爲一個的單詞

 

7二、題目要求  :  打印正方形

題目要求

交互式腳本,根據提示,須要用戶輸入一個數字做爲參數,最終打印出一個正方形。在這裏我提供一個linux下面的特殊字符■,能夠直接打印出來。

示例: 若是用戶輸入數字爲5,則最終顯示的效果爲

■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■

【核心要點】

echo -n 不換行

參考答案

#!/bin/bash
#這個腳本用來打印正方形
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-11

while :
do
    read -p "Please input a nuber: " n
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ -n "$n1" ]
    then
        echo "$n is not a nuber."
        continue
    else
	break
    fi
done

for i in `seq 1 $n`
do
    for j in `seq 1 $n`
    do
	echo -n "■ "
    done
    echo 
done

實例 :

打印出來,一列三行。

添加for循環

顯示三排三列方塊,方塊後面要有空格。

執行腳本,查看結果。輸入數字幾,就顯示幾行幾列方塊。

注意  : 

n1=`echo $n|sed 's/[0-9]//g'`                                #清空全部的數字
if [ -n "$n1" ]                     #若是n1,不爲空。

 

for i in `seq 1 $n`                      #打印$n行。

 for j in `seq 1 $n`                      #打印$n行,$n列。

 

7三、題目要求   :    問候用戶

寫一個腳本,依次向/etc/passwd中的每一個用戶問好,而且說出對方的ID是什麼,如:

Hello, root,your UID is 0.

【核心要點】

對/etc/passwd每一行作遍歷,截取第一段用戶名和第三段uid,而後格式化輸出便可

參考答案

#!/bin/bash
#這個腳本用來問候用戶
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-11

cat /etc/passwd |while read line
do
    username=`echo $line|awk -F ':' '{print $1}'`
    uid=`echo $line|awk -F ':' '{print $3}'`
    echo "Hello, $username, your uid is $uid."
done

實例 :

uid在第三段,用戶名在第一段,截取出來。而後說  " Hello your uid is $3 "

執行腳本,查看結果

注意  : 

username=`echo $line|awk -F ':' '{print $1}'`                                #打印出來,第一段的username.

uid=`echo $line|awk -F ':' '{print $3}'`                              #打印出來,第一段的uid.

 

7四、題目要求  :   格式化輸出xml

linux系統 /home目錄下有一個文件test.xml,內容以下:

<configuration>
    <artifactItems>
        <artifactItem>
       <groupId>zzz</groupId>
       <artifactId>aaa</artifactId>
    </artifactItem>
    <artifactItem>
       <groupId>xxx</groupId>
       <artifactId>yyy</artifactId>
    </artifactItem>
    <!-- </artifactItem><groupId>some groupId</groupId>
       <version>1.0.1.2.333.555</version> </artifactItem>-->
    </artifactItems>
</configuration>

請寫出shell腳本刪除文件中的註釋部份內容,獲取文件中全部artifactItem的內容,並用以下格式逐行輸出: artifactItem:groupId:artifactId:aaa

【核心要點】

參考答案

#!/bin/bash
#這個腳本用來格式化xml文件
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-11

sed '/<!--.*-->/d' test.xml > test2.xml
egrep -n '<!--|\-\->' test2.xml |awk -F ':' '{print $1}' > /tmp/line_number1.txt
n=`wc -l /tmp/line_number1.txt|awk '{print $1}'`
n1=$[$n/2]
for i in `seq 1 $n1`
do
    j=$[$i*2]
    k=$[$j-1]
    x=`sed -n "$k"p /tmp/line_number1.txt`
    y=`sed -n "$j"p /tmp/line_number1.txt`
    sed -i "$x,$y"d test2.xml
done

grep -n 'artifactItem>' test2.xml |awk '{print $1}' |sed 's/://' > /tmp/line_number2.txt
n2=`wc -l /tmp/line_number2.txt|awk '{print $1}'`

get_value(){
    sed -n "$1,$2"p test2.xml|awk -F '<' '{print $2}'|awk -F '>' '{print $1,$2}' > /tmp/value.txt
    
    cat /tmp/value.txt|while read line
    do
        x=`echo $line|awk '{print $1}'`
        y=`echo $line|awk '{print $2}'`
        echo artifactItem:$x:$y
    done
}

n3=$[$n2/2]
for j in `seq 1 $n3`
do
    m1=$[$j*2-1]
    m2=$[$j*2]
    nu1=`sed -n "$m1"p /tmp/line_number2.txt`
    nu2=`sed -n "$m2"p /tmp/line_number2.txt`
    nu3=$[$nu1+1]
    nu4=$[$nu2-1]
    get_value $nu3 $nu4
done

實例 :

查看/tmp/line_number1.txt中的行數

求出來groupID和artifactID對應的值

執行腳本,查看結果 ; 列出來groupID、artifactlID、groupID、artigfactID對應的id.

注意  : 
sed '/<!--.*-->/d' test.xml > test2.xml                              #/d刪除'/<!--.*-->/d'裏面的內容,並重定向到test2.xml     
egrep -n '<!--|\-\->' test2.xml |awk -F ':' '{print $1}' > /tmp/line_number1.txt                 #只查找'<!--|\-\->'前面的行號,並打印出來 ,並寫入到/tmp/line_number1.txt  

 

j=$[$i*2]                                      #$便利的數字,乘以2,就是偶數了
k=$[$j-1]   

x=`sed -n "$k"p /tmp/line_number1.txt`                  #取得數字,11
y=`sed -n "$j"p /tmp/line_number1.txt`                  #取得數字,12
sed -i "$x,$y"d test2.xml                   #11到12直接刪除

 

for i in `seq 1 $n1`                               #1到$n1

n1=$[$n/2]                      #$n除以2,緣由:查看有幾對行號

wc -l /tmp/line_number1.txt|awk '{print $1}'                    #統計過濾出來的/tmp/line_number1.txt中的對數,並打印出對數。

 

7五、題目要求  :     小函數

請撰寫一個shell函數,函數名爲 f_judge,實現如下功能

  1. 當/home/log目錄存在時將/home目錄下全部tmp開頭的文件或目錄移到/home/log目錄。

  2. 當/home/log目錄不存在時,建立該目錄,而後退出。

【核心要點】

一、[ -d /home/log ]判斷目錄是否存在

二、查找tmp開頭的文件或目錄命令是find /home -name "tmp"

參考答案

#!/bin/bash
#這個腳本用來寫一個小函數
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-11

f_judge()
{
    if [ -d /home/log ]
    then
	#find /home -name "tmp*" |xargs -i mv {} /home/log/
	find /home -name "tmp*" -exec mv {} /home/log/ \;
    else
	mkdir /home/log
	exit
    fi
}

f_judge

實例 :

執行腳本,查看結果

注意  :

find /home -name "tmp*" |xargs -i mv {} /home/log/                    #查找/home目錄下全部tmp開頭的文件或目錄移到/home/log目錄。

find /home -name "tmp*" -exec mv {} /home/log/ \;              #查找/home目錄下全部tmp開頭的文件或目錄移到/home/log目錄。

 

 

7六、題目要求   :    批量殺進程

linux系統中,目錄/root/下有一個文件ip-pwd.ini,內容以下:

10.111.11.1,root,xyxyxy
10.111.11.2,root,xzxzxz
10.111.11.3,root,123456
10.111.11.4,root,xxxxxx
……

文件中每一行的格式都爲linux服務器的ip,root用戶名,root密碼,請用一個shell批量將這些服務器中的全部tomcat進程kill掉。

【核心要點】

expect

參考答案

#!/bin/bash
#這個腳本用來批量殺tomcat進程
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-12

cat > kill_tomcat.expect <<EOF
#!/usr/bin/expect
set passwd [lindex \$argv 0]
set host [lindex \$argv 1]
spawn ssh root@\$host

expect {
    "yes/no" { send "yes\r"; exp_continue}
    "password:" { send "\$passwd\r" }
}

expect "]*"
send "killall java\r"
expect "]*"
send "exit\r"
EOF

chmod a+x kill_tomcat.expect

cat ip-pwd.ini|while read line
do
    ip=`echo $line |awk -F ',' '{print $1}'`
    pw=`echo $line |awk -F ',' '{print $3}'`
    ./kill_tomcat.expect $pw $ip
done

實例 :

遠程殺死Tomcat的進程

 

注意  :

expect "]*"                      #]*匹配到的關鍵詞,*表示統配
send "killall java\r"                       #發送killall java指令

 

set passwd [lindex \$argv 0]                       #
set host [lindex \$argv 1]                             #
spawn ssh root@\$host                                 #登陸機器,而後執行指令

 

cat > kill_tomcat.expect <<EOF                   #查看執行的結果,而後結束

chmod a+x kill_tomcat.expect                   #添加執行權限kill_tomcat.expect 

 

ip=`echo $line |awk -F ',' '{print $1}'`                     #IP在第一段,打印出來
pw=`echo $line |awk -F ',' '{print $3}'`              #密碼在第三段,打印出來
./kill_tomcat.expect $pw $ip                 #而後執行kill_tomcat.expect腳本,第一個參數,第二參數,批量遠程執行。

 

 

7七、題目要求   :     查找老日誌打包

寫一個腳本查找/data/log目錄下,建立時間是3天前,後綴是*.log的文件,打包後發送至192.168.1.2服務上的/data/log下,並刪除原始.log文件,僅保留打包後的文件。

【核心要點】

find ./ mtime +3

參考答案

#!/bin/bash
#這個腳本用來查找老日誌打包
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-12

cd /data/log
find . -type f -name "*.log" -mtime +3 > /tmp/old_log
d=`date +%F`

tar czf $d.tar.gz `cat /tmp/old_log|xargs`
rsync -a $d.tar.gz 192.168.1.2:/data/log/
cat /tmp/old_log|xargs rm

實例 :

把文檔中的內容,顯示在一行

執行腳本,查看結果

 

注意  : 

find . -type f -name "*.log" -mtime +3 > /tmp/old_log             #查找3天前,建立的文件後綴是*.log的文件,並重定向到/tmp/old_log文件中。
d=`date +%F`                      #打印出當前的時間

tar czf $d.tar.gz `cat /tmp/old_log|xargs`                         # 打包的包名,是當前的日期發送到/tmp/old_log,並顯示在一行
rsync -a $d.tar.gz 192.168.1.2:/data/log/                       #打包後發送至192.168.1.2服務上的/data/log下
cat /tmp/old_log|xargs rm                                       #查看,刪除原始.log文件,

 

7八、題目要求   :    處理文本

若是第一段同樣的,規列到下面,有以下文本,其中前5行內容爲

1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123

用shell腳本處理後,按下面格式輸出:

[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123

【核心要點】

第一段排序,而後遍歷

參考答案

#!/bin/bash
#這個腳本用來處理文本
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-12

for w in `awk -F ':' '{print $1}' 3.txt |sort |uniq`
do 
    echo "[$w]"
    awk -v w2=$w -F ':' '$1==w2 {print $2}' 3.txt
done

實例 :

截取2.txt第一段,排序,去重複。

執行腳本,查看結果。

awk傳遞一個shell變量到awk中,變成w2,當 $1等於w2的狀況下,而後打印第二段。對文檔進行排序。

注意  : 

for w in `awk -F ':' '{print $1}' 3.txt |sort |uniq`                 #查找並打印出第一行,排序,去重複。for w in :循環遍歷。
 
awk -v w2=$w -F ':' '$1==w2 {print $2}' 3.txt                 #傳遞一個shell變量到$2,而後打印第二段。

 

 

7九、題目要求  :   批量刪除日誌

需求背景: 服務器上,跑的lamp環境,上面有不少客戶的項目,每一個項目就是一個網站。 因爲客戶在不斷增長,每次增長一個客戶,就須要配置相應的mysql、ftp以及httpd。這種工做重複性很是強的,因此用腳本實現很是合適。mysql增長的是對應客戶項目的數據庫、用戶、密碼,ftp增長的是對應項目的用戶、密碼(使用vsftpd,虛擬用戶模式),httpd就是要增長虛擬主機配置段。

參考答案

要求:兩類機器一共300多臺,寫個腳本自動清理這兩類機器裏面的日誌文件。在堡壘機批量發佈,也要批量發佈到crontab裏面。

A類機器日誌存放路徑很統一,B類機器日誌存放路徑須要用匹配(由於這個目錄裏除了日誌外,還有其餘文件,不能刪除。匹配的時候可用.log)

A類:/opt/cloud/log/ 刪除7天前的 B類: /opt/cloud/instances/ 刪除15天前的

要求寫在一個腳本里面。不用考慮堡壘機上的操做,只須要寫出shell腳本。

【核心要點】

判斷機器是A類仍是B類是關鍵點

參考答案

#!/bin/bash
#這個腳本用來刪除老日誌
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-12

dir1=/opt/cloud/log/
dir2=/opt/cloud/instance/

if [ -d $dir1 ]
then
    find $dir1 -type f -mtime +7 |xargs rm
elif [ -d $dir2 ]
then
    find $dir2 -name "*.log" -type f -mtime +15 |xargs rm
fi

實例 :

執行腳本,查看結果。

注意  : 

find $dir2 -name "*.log" -type f -mtime +15 |xargs rm        #查找目錄2中,15天前的日誌,並刪除15天前的的日誌。

find $dir1 -type f -mtime +7 |xargs rm                       #查找目錄1中,7天前的日誌,並刪除7天前的的日誌。

if [ -d $dir1 ]                              #若是目錄1存在執行下一步查找。

elif [ -d $dir2 ]                           #若是目錄2存在執行下一步查找。

 

80、題目要求   :   房貸計算器

貸款有兩種還款的方式:等額本金法等額本息法,簡單說明一下等額本息法與等額本金法的主要區別:

等額本息法特色是:每個月的還款額相同,在月供中「本金與利息」的分配比例中,前半段時期所還的利息比例大、本金比例小,還款期限過半後逐步轉爲本金比例大、利息比例小。所支出的總利息比等額本金法多,並且貸款期限越長,利息相差越大。 等額本金法的特色是:每個月的還款額不一樣,它是將貸款額按還款的總月數均分(等額本金),再加上上期剩餘本金的月利息,造成一個月還款額,因此等額本金法第一個月的還款額最多 ,然後逐月減小,越還越少。所支出的總利息比等額本息法少。

兩種還款方式的比較不是咱們今天的討論範圍,咱們的任務就是作一個貸款計算器。其中:

等額本息每個月還款額的計算公式是:

每個月還款額=[貸款本金×月利率×(1+月利率)^還款月數]÷[(1+月利率)^還款月數-1]

等額本金每個月還款額的計算公式是:

每個月還款額=貸款本金÷貸款期數+(本金-已歸還本金累計額)×月利率

【核心要點】

搞清楚公式

參考答案

#!/bin/bash
#這個腳本用來實現簡易的房貸計算器
#做者:猿課-阿銘 www.apelearn.com
#日期:2018-12-12

read -p "請輸入貸款總額(單位:萬元):" sum_w
read -p "請輸入貸款年利率(如年利率爲6.5%,直接輸入6.5):" y_r
read -p "請輸入貸款年限(單位:年):" y_n
echo "貸款計算方式:"
echo "1)等額本金計算法"
echo "2)等額本息計算法"
read -p "請選擇貸款方式(1|2)" type
#貸款總額
sum=`echo "scale=2;$sum_w*10000 " | bc -l`
#年利率
y_r2=`echo "scale=6;$y_r/100 " | bc -l`
#月利率
m_r=`echo "scale=6;$y_r2/12 " | bc -l`
#期數
count=$[$y_n*12]
echo "期次 本月還款額 本月利息 未還款額"

jin()
{
    #月還款本金m_jin=貸款總額sum/期數count
    m_jin=`echo "scale=2;($sum/$count)/1 " | bc -l`
    #定義未還本金r_jin(第一期應該是貸款總額)
    r_jin=$sum
    for((i=1;i<=$count;i++))
    do
        #本月利息m_xi=剩餘本金*月利率
        m_xi=`echo "scale=2;( $r_jin*$m_r)/1"|bc -l`
        #本月還款m_jinxi=月還本金m_jin+本月利息m_xi
        m_jinxi=`echo "scale=2;( $m_jin+$m_xi)/1"|bc -l`
        #已還款本金jin=月還本金m_jin*期數i
        jin=`echo "scale=2;( $m_jin*$i)/1"|bc -l`
        #剩餘本金r_jin=貸款總額sum-已還本金jin
        r_jin=`echo "scale=2;( $sum-$jin)/1"|bc -l`
        if [ $i -eq $count ]
        then
            #最後一月的還款額應該是每個月還款本金+本月利息+剩餘本金
            m_jinxi=`echo "scale=2;( $m_jin+$r_jin+$m_xi)/1"|bc -l`
            #最後一月的剩餘本金應該是0
            r_jin=0
        fi
        echo "$i  $m_jinxi  $m_xi  $r_jin"
     done   
}

xi()
{
    #每期還款m_jinxi=(貸款總額sum*月利率m_r*((1+月利率m_r)^期數count))/(((1+月利率m_r)^期數count)-1)
    m_jinxi=`echo "scale=2;(($sum*$m_r*((1+$m_r)^$count))/(((1+$m_r)^$count)-1))/1 " | bc -l`
    #定義未還本金r_jin(第一期應該是貸款總額)
    r_jin=$sum
    for((i=1;i<=$count;i++))
    do
        #本期利息m_xi=剩餘本金r_jin*月利率m_r
        m_xi=`echo "scale=2;( $r_jin*$m_r)/1"|bc -l`
        #本期本金m_jin=本期本息m_jinxi-本期利息m_xi
        m_jin=`echo "scale=2;($m_jinxi-$m_xi)/1 " | bc -l`
        #未還本金r_jin=上期未還本金r_jin-本期應還本金m_jin
        r_jin=`echo "scale=2;($r_jin-$m_jin)/1 " | bc -l`
        if [ $i -eq $count ]
        then
            #最後一月本息m_jinxi=本期本金m_jin+未還本金r_jin
            m_jinxi=`echo "scale=2;($m_jin+$r_jin)/1 " | bc -l`
            #最後一月的剩餘本金應該是0
            r_jin="0.00"
        fi
        echo "$i $m_jinxi $m_xi $r_jin"
    done
}

case $type in
    1) 
        jin
        ;;
    2) 
	xi
        ;;
    *) 
	exit 1
        ;;
esac

實例 :

執行腳本,查看結果.

注意  : 

#貸款總額
sum=`echo "scale=2;$sum_w*10000 " | bc -l`                  #scale=2表示小數點2位 ;$sum_w*10000表示乘以10000
#年利率 
y_r2=`echo "scale=6;$y_r/100 " | bc -l`                #scale=6表示小數點六位 ;$y_r/100表示年利率除以100。
#月利率 
m_r=`echo "scale=6;$y_r2/12 " | bc -l`                 #scale=6表示小數點六位 ;$y_r2/12表示月利率除以12

 

若是有能力提早還款,選擇第一種 : 等額本金法。

等額本息法 : 意思是利息相同,每個月還款相同 ;提早還款,也要還利息銀行工做人員通常會推薦你等額本息法,讓你多還錢。

 

來源 :https://github.com/aminglinux/shell100/blob/master/61.md

相關文章
相關標籤/搜索