shell基础编程实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013862108/article/details/83788505

shell  编程 实例

案例:

  1. 字符串截取  ?

使用 ${}  怎么做 截取?

[root@work ~]# SCHOOL="Tarena IT Group."

[root@work ~]# echo ${#SCHOOL}

16

[root@work ~]# echo ${SCHOOL::6}

Tarena

[root@work ~]# echo ${SCHOOL:0:6}

Tarena

[root@work ~]# echo ${SCHOOL:1:6}

arena

[root@work ~]#

使用expr substr  怎么截取?

[root@work ~]# SCHOOL="Tarena IT Group."

[root@work ~]# expr substr "$SCHOOL" 1 6    //必须加引号 注意

Tarena

使用 cut 工具 怎么分隔?

[root@work ~]# SCHOOL="Tarena IT Group."

[root@work ~]# echo $SCHOOL | cut -b 1-6

Tarena

[root@work ~]# echo $SCHOOL | cut -b -6

Tarena

[root@work ~]# echo $SCHOOL | cut -b 8-

IT Group.

[root@work ~]# echo $SCHOOL | cut -b 9

T

字符串怎么 替换?

[root@work ~]# SCHOOL="Tarena IT Group."

[root@work ~]# echo ${SCHOOL/r/XXX}

TaXXXena IT Group.

[root@work ~]# echo ${SCHOOL//r/XXX}

TaXXXena IT GXXXoup.

[root@work ~]# echo ${SCHOOL/$SCHOOL/xxx}

xxx

字符串怎么匹配删除 ?

[root@work ~]# echo $MAIL

/var/spool/mail/root

[root@work ~]# echo ${MAIL#*oo}

l/mail/root

[root@work ~]# echo ${MAIL##*oo}

t

[root@work ~]# echo ${MAIL##*/}

root

[root@work ~]# echo $MAIL

/var/spool/mail/root

[root@work ~]# echo ${MAIL%oo*}

/var/spool/mail/r

[root@work ~]# echo ${MAIL%%oo*}

/var/sp

批量修改当前目录下的文件扩展名 将.doc 改为.txt?

[root@work ~]# more rename.sh

#!/bin/bash

for FILE in *.doc

do

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

done

带参数 $1, $2   如: ./rename.sh .txt .doc

[root@work ~]# more rename.sh

#!/bin/bash

for FILE in *"$1"

do

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

done

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

[root@work ~]# echo $SCHOOL

Tarena IT Group

[root@work ~]# echo ${SCHOOL:-Tarena}

Tarena IT Group

[root@work ~]# echo $SCHOOL

Tarena IT Group

[root@work ~]# unset SCHOOL

[root@work ~]# echo ${SCHOOL:-Tarena}

Tarena

[root@work ~]# echo $SCHOOL

[root@work ~]#

//变量值不存在情况

[root@work ~]# echo $SCHOOL

[root@work ~]# echo ${SCHOOL:=Tarean}

Tarean

[root@work ~]# echo $SCHOOL

Tarean

//变量值存在的情况

[root@work ~]# echo $SCHOOL

Tarean

[root@work ~]# echo ${SCHOOL:=Tarena IT Group.}

Tarean

[root@work ~]# echo $SCHOOL

Tarean

从键盘读入一个正整数x, 求从 1到 x 的和; 当用户未输入值时, 为了避免出错,x赋初值1.  ?

[root@work ~]# 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 是被当为字符串的  怎么 加减乘除运算 ?

[root@work ~]# A=1+2

[root@work ~]# echo $A

1+2

[root@work ~]# X=24

[root@work ~]# A=$X+2

[root@work ~]# echo $A

24+2

[root@work ~]# declare -i A

[root@work ~]# A=1+2

[root@work ~]# echo $A

3

[root@work ~]# declare -i B=$X+2

[root@work ~]# echo $B;

26

//declare -x  可以将局部变量设置为全局变量

//  -r  是只读

怎么定义数组, 怎么获取元素, 总数等 ?

[root@work ~]# MY_SVRS=(www ftp mail club)

[root@work ~]# echo ${MY_SVRS[@]}

www ftp mail club

[root@work ~]# echo ${MY_SVRS}

www

[root@work ~]# echo ${MY_SVRS[0]}

www

[root@work ~]# echo ${MY_SVRS[@]:1:2}

ftp mail

[root@work ~]# echo ${#MY_SVRS[@]}

4

怎么 实现 ssh 自动登录脚本 ,主要用到了什么功能?

[root@work ~]# more ./expect_ssh.sh

#!/usr/bin/expect



set host 192.168.3.154

set user root

set password "123qwe"



spawn  ssh  $user@$host



expect {

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

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

}



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

interact


使用正则表达式 :

[root@work ~]# grep '^root|^daemon' /etc/passwd

[root@work ~]# grep '^root\|^daemon'  /etc/passwd

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

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

[root@work ~]# grep -E '^root|^daemon' /etc/passwd

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

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

[root@work ~]# egrep '^root|^daemon' /etc/passwd

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

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

我 只是想判断是否也有复合正则 ,不需要输出 怎么做?

使用 -q ; quiet 静默

[root@work ~]# grep -q '^192.168' /etc/hosts && echo "yes" || echo "no"

怎么输出匹配到的行数?

[root@work ~]# egrep -c '/sbin/nologin$' /etc/passwd

31

[root@work ~]# egrep '/sbin/nologin$'  /etc/passwd | wc -l

31

怎么匹配 某个单词?怎么匹配以ll结尾的单词的行 ?

[root@work ~]# egrep '\binit\b' /etc/rc.local

[root@work ~]# egrep '\<init\>' /etc/rc.local

[root@work ~]# egrep 'll\>' /etc/rc.local

[root@work ~]# 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 命令 实例:

输出 文件第一行?

[root@work ~]# sed -n '1p'  /etc/passwd

删除  文件 1-4行文本  ?

[root@work ~]# sed '1,4d'  rc.local

//注意不用加 -n

直接 删除原文件 1-4行 文本。?

使用 -i 选项

[root@work ~]# sed -i  '1,4d' rc.local

怎么指定多个编辑指令?比如  输出 第一行,第四行内容?

使用  -e    或  ;  (分号)

[root@work ~]# sed  -n  -e '1p' -e '4p'  rc.local

[root@work ~]# sed -n '1p;4p'  rc.local

[root@work ~]# sed -n '{1p;4p}'  rc.local

输出所有行,?相当于 cat命令

[root@work ~]# sed -n 'p'  rclocal.txt

输出第 2行及 之后的3行?

[root@work ~]# sed -n '2,+3p'  rclocal.txt

输出以 xxx (local) 结尾的 行 ?

[root@work ~]# sed -n  '/local$/p' rclocal.txt

输出奇数行?

[root@work ~]# sed  -n 'p;n' rclocal.txt

输出偶数行?

[root@work ~]# sed -n 'n;p'  rclocal.txt

输出最后一行?

[root@work ~]# sed -n '$p' rclocal.txt

输出文件的 总的行数?

[root@work ~]# sed -n '$='  rclocal.txt

删除 包含 init  ,  bin的行 ?

[root@work ~]# sed '/init/d;/bin/d'  rclocal.txt

删除  不包含init 的行  删除  ?

!d

[root@work ~]# sed  '/init/ !d'  rclocal.txt

p

[root@work ~]# sed -n '/init/p'  rclocal.txt

删除所有空行  ?

^$

[root@work ~]# sed  '/^$/d'   rclocal.txt

替换 s

将 所有行   第一个ll  替换为  “XX”  ?

[root@work ~]# sed 's/ll/XX/'  rclocal.txt

将 所有行 中 所有 ll  替换为  “XX” ?

[root@work ~]# sed  's/ll/XX/g'  rclocal.txt

将第3行内 的 第2个 “script”  替换为  “XX” ?

[root@work ~]# sed '3s/script/XX/2'  rclocal.txt

删除 指定的字符串 ?

替换为空

[root@work ~]# sed 's/init//g' rclocal.txt

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

或的关系 要用 \|  来表示

[root@work ~]# sed 's/script\|stuff\|e//g' rclocal.txt

去掉3-5 行的注释?

[root@work ~]# sed  '3,5s/^#//'  rclocal.txt

将 /etc/rc.local 文件 的第 6-7行 注释掉 ?

行首添加 #

[root@work ~]# sed '6,7s/^/#/'  rclocal.txt

将 文件每行 第1 个字符, 第二个字符交换?

-r  启用正则扩展  \2  引用第二个()匹配到的。

[root@work ~]# sed -r 's/^(.)(.)/\2\1/' rclocal.txt

删除行首 空格 ?

[root@work ~]# sed -r 's/^( )+//'  rclocal.txt

为文件中每个大些字母添加 括号?

&  代表 匹配到的 整个字符串

[root@work ~]# sed  's/[A-Z]/(&)/g' rclocal.txt

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

对网卡 配置文件 eth0 的修改 :

将IP地址 192.168.3.135 修改为   192.168.3.136 ?

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

[root@work ~]# sed -i '/IPADDR/s/192.168.3.29/192.168.3.136/'  /etc/sysconfig/network-scripts/ifcfg-eth0

sed 的多行操作:

c : 替换指定的行

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

a  :  在指定的行 后追加 文本

sed 怎么整行替换呢:?

修改主机名 ?

c  : 替换 指定的行

[root@work ~]# sed -i  '/^HOSTNAME/cHOSTNAME=liang'  /etc/sysconfig/network

在 hosts 文件中, 添加两行记录 (a追加)

[root@work ~]# 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  是 怎么指定分隔符 呢?

默认是:不指定 就是 空格 或 制表符 做分隔;

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

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

awk 怎么指定多个分隔符呢?

[root@work ~]# awk -F [:/]  '{print $1,$10}' /etc/passwd

awk 有哪些内置的变量 ? 当前行号,列数  文件名?

[root@work ~]# awk '{print FILENAME,NR}' /etc/passwd

[root@work ~]# awk -F[:/] '{print NR,NF}' /etc/passwd

awk  怎么使用环境变量?   输出当前用户的passwd的记录?

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

统计使用bash 作为登录shell 的用户总个数?

思路: 在begin 定义 计数变量 ; \< bash 匹配bash

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

[root@work ~]# egrep -c '\<bash$' /etc/passwd

从ifconfig eth0  提取IP地址?

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

根分区 使用率?

[root@work ~]# df -hT / | tail -1 | awk '{print $5}'

分析/etc/passwd 文件  输出 列表头; 用户信息,bash信息,, 尾部:行数, 统计信息。

[root@work ~]# awk -F: 'BEGIN{print "User\tUID\tHome"} \

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

输出 其中登录shell 不以nologin结尾 的用户名,登录shell信息?

第七个字段 !~ 反向匹配

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

输出第3行的用户记录?

NR ==3

[root@work ~]# awk -F: 'NR==3{print}' /etc/passwd

输出奇数行的用户记录?

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

输出偶数行的用户记录?

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

输出前3行用户记录?

[root@work ~]# awk -F: 'NR<=3{print}' /etc/passwd

输出第3-5 行 用户记录?

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

输出 登录shell 不以nologin 结尾 或者 用户名 以 a 或d 开头 的文本 ?

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

统计文件中 字段个数  ?

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

列出100以内 整数中7的倍数 或是含7的数?

[root@work ~]# seq 100 | awk '$0%7==0||$0~/7/{print}'

awk 流程控制考察。

统计/etc/passwd 文件中登录shell不是“/bin/bash” 的用户个数:?

单分支

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

统计  /etc/passwd 文件中UID 小于或等于500, UID 大于500的用户个数:?

双分支

[root@work ~]# 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 ,其他用户 的个数 ?

[root@work ~]# 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  出现的次数  ?

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

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

计算从1-100内各整数的总和 ?

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

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

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

跳过 当前 行 ?

next

[root@work ~]# awk 'NF<=2{next}{print}' /etc/rc.local

去处重复的行?

[root@work ~]# awk '!a[$0]++' a1.txt

[root@work ~]# awk '!a[$0]++{print $0}' a1.txt

统计web 访问日志 /var/log/httpd/access_log  统计IP 访问量 ; 按访问量排序?

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

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

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

参考 tts-shell  day06练习。

猜你喜欢

转载自blog.csdn.net/u013862108/article/details/83788505