Linux shell脚本 扩展补充示例

通过变量切片、获取变量长度、产生随机数、合并字符串,最后生成随机密码

变量切片、获取变量长度

[xue@xue ~]$ a='1234567890'
[xue@xue ~]$ echo $a
[xue@xue ~]$ echo ${a}
[xue@xue ~]$ echo ${#a}    #获取变量长度
[xue@xue ~]$ echo ${a:3:3} #切片,第4个开始获取三个字符(4-6)
[xue@xue ~]$ echo ${a:7:2}
[xue@xue ~]$ echo ${a:5:1}

  

产生随机数

原理:RANDOM随机数(0-32767)取余a变量长度(10),即可获得随机个位数,属于简便的写法

最后用获得的个位随机数结果写入tmp,使用tmp的值作为位置在变量a中分片1位,以做到以变量a为密码池生成密码的效果

[xue@xue ~]$ echo ${a}  #显示变量
[xue@xue ~]$ echo ${#a} #变量长度
[xue@xue ~]$ echo $[RANDOM % ${#a}]
[xue@xue ~]$ echo $[RANDOM % ${#a}]
[xue@xue ~]$ echo $[RANDOM % ${#a}] 
[xue@xue ~]$ echo $[RANDOM % ${#a}]
[xue@xue ~]$ echo $[RANDOM % ${#a}]
#生成随机数,用其对变量长度(10)取余,获得个位随机数

合并字符串

 

 用上面的知识点生成随机密码

先取余获取个位随机数,用这个数作为str变量切片的开始位置并切片一位,循环8次,每次字符串合并追加,完成随机密码创建。(生成的密码所包含的字符取自str)

str='1234567890'

for i in {1..8}
do
    a=$[RANDOM % ${#str}]  #对随机数用str长度取余,获得一位的随机数
    tmp=${str:a:1}  #用一位随机数作为位置变量,对str随机切片
    pasw+=$tmp      #合并到pasw字符串中
done
echo "随机密码为: $pasw"

将0-255的十进制数转化为二进制数

除二取余倒排法

read -p "输入0-255整数" num

for i in {1..8}
do
    a=$[num % 2]$a     #取余,结果拼接到a前,完成余数倒排
    let num=$[num / 2] #将num除二,进入下一个循环
done
echo $a

减数正排法

输入的num减去for列表中的减数,能减去则输出1,并更改num减去刚刚的减数进行下一次循环。若减不进则输出0,直接下一个循环。

read -p "输入0-255整数" num

for i in {128,64,32,16,8,4,2,1}
do
    NUM=$[num - i]    #NUM作为预判断变量,先不对num直接处理
    if [ $NUM -lt 0 ] #判断是否能减进
    then
        echo -n 0     #减不进输出0,不对num处理,进入下一轮循环
    else
        echo -n 1     #能减进输出1   #-n不换行输出
        num=$[num-i]  #能减进输出则对num减去i,再进入下一轮循环
        #let num-=i   #与上句同义
    fi
done
echo ''

echo -e

echo -e "123\n456"      #换行
echo -e "123\c456"      #不换行
echo -n "123456"        #不换行

echo -e "123\t456"      #归档
echo -e "123\f456"      #归档换行
echo -e "123\v456"      #归档换行
echo -e "123\v456\f789" #归档换行
    
echo -e "123\r456"      #替换
echo -e "1234\r456"     #替换只能一样长度的!

awk 筛选列

[xue@xue ~]$ free -m    #查看内存
              total        used        free      shared  buff/cache   available
Mem:           3931        1078         806          86        2046        2509
Swap:          3968           0        3968


[xue@xue ~]$ free -m | grep Mem  #筛选MEM
Mem:           3931        1079         806          86        2046        2509


[xue@xue ~]$ free -m | grep Mem |awk '{print $3}'
1079      #再次筛选MEM行第三列

使用多种方法筛选文本(awk、切片)

echo '10.11.12.13' | awk -F. '{print $3}'  #以 . 分隔的第三段
i='10.11.12.13'

echo ${i:3:2}    #从第三位开始切2个字符

echo ${i%%.*}    #从后向前删到第一个 .
10
echo ${i%.*}     #从后向前删到最后一个 .
10.11.12
echo ${i#*.}     #从前向后删到第一个 .
11.12.13
echo ${i##*.}    #从前向后删到最后一个 .
13

循环读取文件内容

for a in $(cat 1.txt)       #不加cat直接输出只能输出文件名!
do
    echo $a
done

while read b
do
echo $b
done < 1.txt    #重定向输出
cat 1.txt | while read c  #cat管道符号
do
  echo $c
done

 seq命令

seq 1 2 10    #从1开始,每隔2,输出直到10
seq 2 3 10    #从2开始,每隔3,输出直到10

猴子摘下来n个香蕉,每天吃掉一半多一个,到第十天就剩一个,猴子第一天摘了多少香蕉?

由于到第十天,使用一共循环了九次。

每天吃掉一半多一个,所以先加上1在乘2.反推9次

#!bin/bash
n=1
for ((i=9;i>0;i--))
do
    n=$[(n+1)*2]
done

echo $n

菲波拉契数

初始ab均为1,每次相加a,b指针都后移一位,a=b,b=a+b。

a=1
b=1
for i in {1..10}
do
  echo $a
  sum=$[ a + b ]
  a=$b
  b=$sum
done

统计菲波拉契数和

a=1
b=1
C=0

for i in {1..10}
do
  echo $a
  C=$[C+a]
  sum=$[a+b]
  a=$b
  b=$sum
done
echo "sum=$C"

大文件分割

[xue@xue ~]$ cat wjfg.sh
a=0 #记录行数
b=1 #记录分隔文件序号标识

for i in $(cat anaconda-ks.cfg)
do
        let a++
        #a满20行c即可整除为0,进入if判断第一行。未满20进入if判断第二行
        c=$[a % 20]
        if [ $c -eq 0 ]
        then #满20句写入文件后,标识符b+1,下一次写入不同标识符的新文件
                echo $i >> ks.cfg-$b
                let b++
        else #不满20句的话写入当前文件,标识符不动,下一次仍然写入这个文件
                echo $i >> ks.cfg-$b
        fi
done

文件分隔了,但是很明显应该是4个文件却生成了9个,这是由于for将空格也算成了分隔符。

全局修改,此处不用,在脚本中修改,以免影响其他脚本

set | grep IFS  #修改IFS配置

IFS_OLD=$IFS    #保存IFS配置到IFS_OLD以便恢复
IFS=$'\n'        #设置IFS='\n',即将IFS=$' \t\n'的空格、制表位删除,只保留换行为分隔符

 修改后的脚本

[xue@xue ~]$ cat wjfg.sh
a=0 
b=1

IFS_OLD=$IFS      #修改IFS,备份 
IFS=$'\n'
 
for i in $(cat anaconda-ks.cfg)
do
        let a++
        c=$[a % 20]
        if [ $c -eq 0 ]
        then 
                echo $i >> ks.cfg-$b
                let b++
        else 
                echo $i >> ks.cfg-$b
        fi
done

IFS=$IFS_OLD      #改回原来的IFS 

输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件

执行命令mkdir -p /root/bin/aa/bb/cc/dd ; touch /root/bin/aa/bb/cc/dd/abc.txt

通过脚本输出环境变量PATH所包含的所有目录以及其中的子目录和所有不可执行文件

#!/bin/bash

IFSB=$IFS
IFS=$IFS':'  
#由于系统变量用:分隔,IFS需要临时添加:分隔符。
#但是不能只设置:  这样会导致识别不了其他的分隔符而导致下方路径拼接错误
#这里使用$IFS':' 表示在原先IFS设置的基础之上再增加:而不是只有一个:作为分隔符

for folder in $PATH    #遍历系统变量中文件夹
do
    ALLFILE=$(find $folder -print)  #使用find -print输出文件夹中所有文件。存储到ALLfile
    for i in $ALLFILE       #遍历每个文件
    do
        if [ -f $i ] && [ -x $i ] #若不是文件并且没有执行权限(目录与不可执行文件)才显示
        then :    #if then 后没有语句,要写成if then: 避免语法错误
        else
            echo $i
        fi
    done
done

IFS=$IFSB #恢复IFS设置

 输出环境变量PATH的目录所包含的所有可执行文件

#!/bin/bash

IFSB=$IFS
IFS=$IFS':'  
#由于系统变量用:分隔,IFS需要临时添加:分隔符。
#但是不能只设置:  这样会导致识别不了其他的分隔符而导致下方路径拼接错误
#这里使用$IFS':' 表示在原先IFS设置的基础之上再增加:而不是只有一个:作为分隔符

for folder in $PATH    #遍历系统变量中文件夹
do
    echo $folder  #显示文件夹
    for file in $folder/*   #遍历文件夹中文件,注意要写全 $folder/* 否则获取的文件为相对路径会导致路径拼接错误 
    do
        if [ -f "${file}" ] && [ -x "${file}" ] #若是文件并且有执行权限才显示
        then 
            echo "    $file"   
        fi

    done
done

IFS=$IFSB #恢复IFS设置

#!/bin/bash

IFSB=$IFS
IFS=$IFS':'  

for folder in $PATH   
do
    echo $folder 
    for file in $(ls $folder) #✨$(ls $folder)是 $folder/*另一种写法 由于获取绝对路径 
    do
        if [ -f "${folder}/${file}" ] && [ -x "${folder}/${file}" ] 
        #✨"${folder}/${file}"是"${file}"另一种写法 由于获取绝对路径 
        then 
            echo "    $file"   
        fi

    done
done

IFS=$IFSB

编写脚本使用 md5sum 命令一次性判别目录中的文件是否有发生过改动

#!/bin/bash

for file in $(ls /opt/test) #遍历文件夹文件,写绝对路径
do
  SUM_NOW=$(md5sum /opt/test/$file | awk '{print $1}')  
  #使用md5sum对文件生成md5信息,md5共有数据与文件名两段,取第一段
  SUM_OLD=$(grep $file /root/md5sum.txt | awk '{print $1}')
  #从之前生成的md5存储文件中获取当前文件的md5信息,取第一段数据

  if [ "$SUM_NOW" != "$SUM_OLD" ] #判定md5是否相同
  then
    echo "$file 文件被改动"
  fi
done

将一个点分十进制格式的IP地址转换成点分二进制格式

比如 255.255.255.255   →  11111111.11111111.11111111.11111111

#!/bin/bash

read -p "请输入一个ip地址: " ip
b=0 #点计数标识,用于下方重新组合ipv4地址时计数生成了几个点

IFSB=$IFS
IFS=$IFS'.'   #临时修改IFS 添加分隔符 . 用于分隔ip地址每一段。

for num in `echo $ip`  #`echo $ip`,写在双撇号内,表示显示ip,传递给for以获取ip的每一段
do

     #↓↓↓二进制转换↓↓↓#
     for i in {128,64,32,16,8,4,2,1} #余数正排法
     do
          NUM=$[$num - $i]    #先不对num操作,用NUM预执行减法,用以判断是否能够减去
          if [ $NUM -lt 0 ]
          then
               echo -n "0"  #不能减去不换行输出0
          else
               echo -n "1"  #能减去不换行输出1
               num=$NUM     #并且对num进行减去操作。(num=$NUM相当于num-=i)
          fi
     done
     #↑↑↑二进制转换↑↑↑#

           #↓↓↓IP地址重组合↓↓↓#
           let b+=1          #每段IP地址经过二进制转换后都在后方重新添加 . 
           if [ $b -lt 4 ]   #添加一次.标识b增加一次,当标识b计数4次后(加了3个点)停止加点
           then
                echo -n "."  #不换行输出 .
           fi
           #↑↑↑IP地址重组↑↑↑#
done
echo

IFS=$IFSB #改回IFS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值