欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

马哥 06_03 bash脚本编程之五 字符串测试及for循环 有大用

image.png

sed练习:


1,删除 /etc/grub.conf文件中行首的空白符

image.png

[root@ebs-22618 ~]# sed -r 's/^[[:space:]]+//' /etc/grub.conf

[root@ebs-22618 ~]# sed  's/^[[:space:]]*//' /etc/grub.conf (好像也行)


2,替换 /etc/inittab文件中 "id:3:initdefault:" 一行中的数字为5

image.png

[root@ebs-22618 ~]# sed -r 's/(id:)[0-9]+(:initdefault)/\15\2/g' /etc/inittab


3,删除/tmp/havespace.txt 文件中的空白行image.png

image.png

[root@ebs-22618 ~]# sed '/^$/d' /tmp/havespace.txt

image.png


4,删除/etc/inittab文件中开头的#号

image.png

[root@ebs-22618 ~]# sed 's/^#//' /etc/inittab   应该加 g(全局) 不加g 都可以



5,删除/etc/inittab文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符

image.png

[root@ebs-22618 ~]# sed -r 's/^#[[:space:]]+//' /etc/inittab    应该加 g(全局) 不加g 都可以



6,删除某文件中以空白字符后面跟#号的行中的开头的空白字符及#号

image.png

image.pngimage.png

[root@ebs-22618 ~]# sed -r 's/^[[:space:]]+#//' test100.txt



7,取出一个文件路径的目录名称

image.png

/etc/aaa /etc/aaa.txt  /etc/aaaa/pass /etc/aaa/pass.txt

[root@ebs-22618 ~]# echo  "/etc/aaa/bbb/" | sed -r  's@^(/.*/)[^/]+/?@\1@'

image.png

下面取基文件名

[root@ebs-22618 ~]# echo  "/etc/aaa/bbb/" | sed -r  's@^/.*/([^/]+)/?@\1@'

image.png


路径如 /etc/aaa/bbbb,/etc/aaa/ 是正确的 但是 /etc 就不对了

[root@ebs-22618 ~]# echo "/etc/passwd/aaa" | sed -r 's@^(/.*/)[^/]+/?@\1@'image.png


基名:

[root@ebs-22618 ~]# echo "/etc/passwd/aaa" | sed -r 's@^/.*/([^/]+)/?@\1@'

image.png


image.png


练习:

image.png


传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来

1)种方法通过查找 /etc/passwd  和 /etc/group 来完成

image.png

#!/bin/bash

#


PARAM_NUM=$#

if [ $PARAM_NUM -lt 1 ]; then

  echo "Usage: judgeuser2.sh ARG1"

  exit 2

fi

GID=`grep "^$1\>" /etc/passwd | cut -d: -f4`

GNAME=`grep "\<$GID\>" /etc/group |cut -d: -f1`

if [ $1 == $GNAME ]; then

  echo "USERNAME is equal GNAME"

else

  echo "USERNMAE is not equal GNAME"

fi



2)种方法

image.png

#!/bin/bash

NUM=$#

if [ $NUM -lt 1 ]; then

  echo "Usage: File.sh ARG1"

  exit 5

fi

if [ `id -n -u $1` == `id -n -g $1` ]; then

  echo "equql"

else

  echo " not equal"

fi




练习:

image.png


传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来 要求保留两位精度,形如:


./calc2.sh 5 / 2                         

./calc2.sh 5 \*  2


image.png

#!/bin/bash

#

NUM=$#

if [ $NUM -lt 3 ]; then

  echo "Usage: calc2.sh ARG1 ARG2 ARG3"

  exit 5

fi

RESULT=`bc <<< "scale=2;$1$2$3"`

echo $RESULT


练习:



字符串比较:

练习:写一个脚本

 传递一个参数(单字符就行)给脚本,如参数为q,就退出脚本,否则就显示用户的参数

 传递一个参数给脚本,如参数为q或Q或quit或Quit,就退出脚本,否则就显示用户的参数


(可以写成或者$1 或者 ....... 可以写成正则$1,可以被 q,Q,quit,Quit 匹配到)

#!/bin/bash

#

if [ $1 = 'q' ];then

    echo "Quiting......"

    exit 1

elif [ $1 == 'Q' ];then

    echo "Quiting......"

    exit 2

elif [ $1 == 'quit' ];then

    echo "Quiting......"

    exit 3

elif [ $1 == 'Quit' ];then

    echo "Quiting......"

    exit 4

else

    echo $1

fi





bc 

image.png

传递3个参数给脚本.参数均为用户名:将这些用户的账号信息提取出来后放置于/tmp/testusers.txt文件中.并要求每一行行首有行号:

echo "1 $LINE" >> /tmp/testusers

echo "2 $LINE" >> /tmp/testusers

echo "3 $LINE" >> /tmp/testusers

image.png


#!/bin/bash

#

NUM=$#

if [ $NUM -lt 3 ]; then

  echo "Usage: File.sh ARG1 ARG2 ARG3"

  exit 5

fi

LINE1=`grep "^$1\>" /etc/passwd`

LINE2=`grep "^$2\>" /etc/passwd`

LINE3=`grep "^$3\>" /etc/passwd`

echo "1 $LINE1"

echo "2 $LINE2"

echo "3 $LINE3"



image.png

image.png

#!/bin/bash

#

PRODUCTOR=`sed -n "/vendor_id/p" /proc/cpuinfo | cut -d: -f2 | sort -u | sed -r 's/^[[:space:]]*//g'`

if [ $PRODUCTOR == 'AuthenticAMD' ]; then

  echo "AMD"

elif [ $PRODUCTOR == 'GenuineInter' ]; then

  echo "Inter"

else

  echo "other $PRODUCTOR"

fi



image.png



MAX=0

MAX -eq $1

MAX=$1

MAX -lt $2

MAX=$2


image.png

#!/bin/bash

#

NUM=$#

if [ $NUM -lt 3 ]; then

  echo "Usage: judgeBig.sh ARG1 ARG2 ARG3 "

  exit 5

fi

MAX=0

if [ $MAX -lt $1 ]; then

  MAX=$1

fi

if [ $MAX -lt $2 ]; then

  MAX=$2

fi

if [ $MAX -lt $3 ]; then

  MAX=$3

fi

echo $MAX

image.png

image.png

只向默认shell为bash的用户问声好 比较简单就不做了

image.png

#!/bin/bash

#

FILE=/etc/passwd

CONTENT=`cat $FILE`

USERNUM=0

for I in $CONTENT; do

  let USERNUM=$USERNUM+1

  USERNAME=`echo $I | cut -d: -f1`

  USERBASH=`echo $I | cut -d: -f6`

  echo "Hello,$USERNMAE, your shell: $USERBASH"

done

  echo "total users count is $USERNUM"


image.png

添加10个用户

image.png

#!/bin/bash

#

for I in {1..10}; do

  if id user${I} &> /dev/null; then

    echo "user${I} exists"

  else

    useradd user${I} | echo user${1} | passwd --stdin user${I} &> /dev/null

    echo "add user user${I}"

  fi

done


添加一个用户

image.png

#!/bin/bash

#

PARAM_NUM=$#

if [ $PARAM_NUM -lt 1 ]; then

  echo "Usage: addoneuser.sh ARG1"

  exit 2

fi

if ! id $1 &> /dev/null; then

  useradd $1

  echo "add one user $1"

else

  echo "$1 exist"

fi

~

删除一个用户

image.png

#!/bin/bash

#

PARAM_NUM=$#

if [ $PARAM_NUM -lt 1 ]; then

  echo "Usage: deleteoneuser.sh ARG1"

  exit 1

fi

if id $1 &> /dev/null; then

  userdel -r $1

  echo "delete $1,and it is home directory"

else

  echo "$1 not exist"

fi






image.png

image.png

#!/bin/bash

#

let SUM=0

for I in {1..100}; do

  MOD_NUM=`expr $I % 3`

  if [ $MOD_NUM -eq 0 ]; then

    SUM=$[$SUM+$I]

  fi

done

echo $SUM



image.png

image.png

#!/bin/bash

#

let ODD_SUM=0

let EVEN_SUM=0

for I in `seq 100`; do

  MOD_VALUE=$[$I % 2]

  if [ $MOD_VALUE -eq 0 ]; then

    EVEN_SUM=$[$EVEN_SUM+I]

  else

    ODD_SUM=$[$ODD_SUM+I]

  fi

done

echo "even sum is $EVEN_SUM"

echo "odd sum is $ODD_SUM"





image.png

image.png


#!/bin/bash

#

BASH_NUM=`grep "bin/bash" /etc/passwd |wc -l`

echo "BASH,${BASH_NUM}users.they are:"

for I in `grep "bin/bash" /etc/passwd`; do

  USERNAME=`echo $I | cut -d: -f1`

  if [ $BASH_USERNAME ]; then

    BASH_USERNAME=$BASH_USERNAME,$USERNAME

  else

    BASH_USERNAME=$USERNAME

  fi

done

echo $BASH_USERNAME


NOLOGIN_NUM=`grep "sbin/nologin" /etc/passwd |wc -l`

echo "nologin,${NOLOGIN_NUM}users.they are:"

for I in `grep "sbin/nologin" /etc/passwd`; do

  USERNAME=`echo $I | cut -d: -f1`

  if [ $NOLOGIN_USERNAME ]; then

    NOLOGIN_USERNAME=$NOLOGIN_USERNAME,$USERNAME

  else

    NOLOGIN_USERNAME=$USERNAME

  fi

done

echo $NOLOGIN_USERNAME




1,......100



image.png


字符测试:(字符串测试)

==  是否等于,相等为真,不等为假(两个等于号,一个等于号都可以)(等号两号都要有空格,否则程序会识别成赋值的而赋值会报错的因为赋值的左边不能有美元符号)

因为 两边 都是 $变量名 所以能判断出 是做测试,而不是做赋值的 

!= 是否不等于,不等为真,相等为假

> 是否大于(很少用)            一般是字符串在前在后的比较

< 是否小于(很少用)           一般是字符串在前在后的比较

>= 是否大于等于(很少用)           一般是字符串在前在后的比较

<= 是否小于等于(很少用)           一般是字符串在前在后的比较

-n string: 判断测试指定字符串是否为空  空则为真,不空则为假 这个肯定不对

if [ str1 = str2 ]       当两个字符串有相同内容、长度时为真 
if [ str1 != str2 ]      当字符串str1和str2不等时为真 
if [ -n str1 ]       当字符串的长度大于0时为真(串非空) 
if [ -z str1 ]        当字符串的长度为0时为真(空串) 
if [ str1 ]         当字符串str1为非空时为真


image.png


字符串变量表达式
If  [ $a = $b ]                 如果string1等于string2,则为真
                                字符串允许使用赋值号做等号
if  [ $string1 !=  $string2 ]   如果string1不等于string2,则为真       
if  [ -n $string  ]             如果string 非空(非0),返回0(true)  
if  [ -z $string  ]             如果string 为空,则为真
if  [ $sting ]                  如果string 非空,返回0 (和-n类似) 

image.png


image.png

image.png

-s string: (刚好相反)测试指定字符串是否不空  不空则为真,空则为假 这个肯定不对



循环: 进入条件,退出条件

1,....,100

常用三种循环

for

while 

until


for 变量  in 列表; do  (变量是不带美元符的     与 if then 一样 ,如果 do 放到下一行,就不要使用分号;了)

    循环体

done


for I in  1 2 3 4 5 6 7 8 9 10; do

    加法运算

done



遍历完成之后,退出


如何生成列表:

{1..100}  花括号,从1至100之间的所有整数

seq [超始数 [步进长度]] 结束数(不一定包括)     # sequence 序列

        `seq [超始数 [步进长度]] 结束数`  程序中我们要用命令替换

`ls /etc` 展开它所有的文件名 (它也可以生成列表)


declare -i SUM  直接声明一个整形的变量

declare -i SUM=0  直接声明一个整形的变量,值为0  (bash是不支持浮点型运算,它只支持整数)

       -i 就是 interger 的意思

let SUM=0 (bash默认是字符串,前面加let 表示它是一个整数)


declare  -x (将一个变量声明为环境变理,相当于 export )






下面三种都可以  可以用一个等于号,也可以用双等于号 两个等于号

[root@ebs-22618 ~]# A=hello

[root@ebs-22618 ~]# B=hi

[root@ebs-22618 ~]# [ $A = $B ]

[root@ebs-22618 ~]# echo $?

image.png

[root@ebs-22618 ~]# [ "$A" = "$B" ]

[root@ebs-22618 ~]# echo $?

image.png

[root@ebs-22618 ~]# [ '$A' = '$B' ]

[root@ebs-22618 ~]# echo $?

image.png




[root@ebs-22618 ~]# A=hello

[root@ebs-22618 ~]# B=hi

[root@ebs-22618 ~]# [ $A != $B ]

[root@ebs-22618 ~]# echo $?

image.png




[root@ebs-22618 ~]# nano testuser.sh

image.png

[root@ebs-22618 ~]# chmod +x testuser.sh

[root@ebs-22618 ~]# ./testuser.sh  root

image.png



[root@ebs-22618 ~]# groupadd hello

[root@ebs-22618 ~]# useradd -g hello hi

[root@ebs-22618 ~]# ./testuser.sh  hi

image.png



[root@ebs-22618 ~]# nano testuser2.sh   (对testuser.sh 进行稍作修改)

image.png


[root@ebs-22618 ~]# bc                  scale 保留精度

image.png



[root@ebs-22618 ~]# echo "scale=2;111/222;" |bc     (两个语句,要用分号隔开)

image.png

[root@ebs-22618 ~]# bc <<< "scale=2;111/22;"    <<< 三个左尖号有点类似于输入重定向

image.png


[root@ebs-22618 ~]# type seq

image.png

[root@ebs-22618 ~]# man seq

image.png


[root@ebs-22618 ~]# seq 10    # 这个是每个结果一行

image.png

[root@mail scripts]# echo `seq 10`  # 这个是所有结果一行

1 2 3 4 5 6 7 8 9 10


[root@ebs-22618 ~]# seq 5 10

image.png


[root@ebs-22618 ~]# seq 2 2  10  超始数 步长 最大值

image.png


[root@ebs-22618 ~]# seq 1 2  10  超始数 步长 最大值(可以不包括)

image.png




image.png


[root@ebs-22618 ~]# nano sum.sh

image.png


[root@ebs-22618 ~]# bash sum.sh

image.png



[root@ebs-22618 ~]# wc -l /etc/passwd

image.png

[root@ebs-22618 ~]# LINES=`wc -l /etc/passwd | cut -d' ' -f1`

image.png


linux 中 回车功能相当于 分号;

[root@ebs-22618 ~]# for I in `seq 1 $LINES`; do echo "hello ` head -n $I /etc/passwd | tail -1 | cut -d: -f1`"; done


image.png



image.png

#!/bin/bash

#

let LINES=`wc -l /etc/passwd | cut -d' ' -f1`

for I in `seq $LINES`; do

  echo "hello `head -n $I /etc/passwd | tail -1 | cut -d: -f1`"

done

~






普通分类: