Linux运维常用shell脚本之文件和字符串管理实例

2022-12-02 14:54:39 浏览数 (1)

1、判断输入是否为数字

代码语言:javascript复制
方法1:
if [[ $1 =~ ^[0-9] $ ]]; then
    echo "Is Number."
else
    echo "No Number."
fi
方法2:
if [ $1 -gt 0 ] 2>/dev/null; then
    echo "Is Number."
else
    echo "No Number."
fi

方法3:

代码语言:javascript复制
echo $1 |awk '{print $0~/^[0-9] $/?"Is Number.":"No Number."}'  #三目运算符
DIR=$1
KEY=$2
for FILE in $(find $DIR -type f); do
    if grep $KEY $FILE &>/dev/null; then
        echo "--> $FILE"
    fi
done

2、 将目录下大于k的文件转移出去

编写shell脚本,将/usr/local/test目录下大于100k的文件转移到/tmp目录下:

代码语言:javascript复制
#!/bin/bash
for FILE in `ls /usr/local/test`
do
    if [ -f $FILE ] ; then
        if [ `ls -l  $FILE | awk `{print $5}` -gt 100000 ] ; then
            mv $FILE  /tmp/
        fi
    fi
done

================

代码语言:javascript复制
#!/bin/bash
for FileName in `ls -l  /usr/local/test | awk '$5>102400' {print $9}`
do
        mv $FileName  /tmp/
done
ls -al  /tmp/
echo  "done!"

3、批量修改文件名

代码语言:javascript复制
# touch article_{1..3}.html

# ls

article_1.html  article_2.html  article_3.html

现在想把article改为bbs:

方法1:

for file in $(ls *html); do

    mv $file bbs_${file#*_}

    # mv $file $(echo $file |sed -r 's/.*(_.*)/bbs1/')

    # mv $file $(echo $file |echo bbs_$(cut -d_ -f2) 

done

方法2:

for file in $(find . -maxdepth 1 -name "*html"); do

     mv $file bbs_${file#*_}

done

方法3:

# rename article bbs *.html

4、ftp自动登录批量下载文件

代码语言:javascript复制
##### 从ftp服务器上的/home/data 到 本地的/home/databackup####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
cd /home/data
lcd /home/databackup
prompt
mget *
close
bye
!

5、ftp自动登录上传文件

代码语言:javascript复制
####本地的/home/databackup to ftp服务器上的/home/data####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
hash
cd /home/data
lcd /home/databackup
prompt
mput *
close
bye
!

6、ftp自动登录下载单个文件

代码语言:javascript复制
####ftp服务器上下载/home/data/a.sh to local /home/databackup####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
cd /home/data
lcd /home/databackup
prompt
get a.sh a.sh
close
bye
!

7、ftp自动登录上传单个文件

代码语言:javascript复制
####把本地/home/databachup/a.sh up ftp /home/databackup 下####
#!/bin/bash
ftp -n<<!
open 192.168.1.171
user guest 123456
binary
cd /home/data
lcd /home/databackup
prompt
put a.sh a.sh
close
bye
!

8、监控目录,将新创建的文件名追加到日志中

需安装inotify-tools软件包。

代码语言:javascript复制
#!/bin/bash
MON_DIR=/opt
inotifywait -mq --format %f -e create $MON_DIR |
while read files; do
  echo $files >> test.log
done
12.16 多个网卡选择
function local_nic() {
    local NUM ARRAY_LENGTH
    NUM=0
    for NIC_NAME in $(ls /sys/class/net|grep -vE "lo|docker0"); do
        NIC_IP=$(ifconfig $NIC_NAME |awk -F'[: ] ' '/inet addr/{print $4}')
        if [ -n "$NIC_IP" ]; then
            NIC_IP_ARRAY[$NUM]="$NIC_NAME:$NIC_IP"    #将网卡名和对应IP放到数组
            let NUM  
        fi
    done
    ARRAY_LENGTH=${#NIC_IP_ARRAY[*]}
    if [ $ARRAY_LENGTH -eq 1 ]; then     #如果数组里面只有一条记录说明就一个网卡
        NIC=${NIC_IP_ARRAY[0]%:*}
        return 0
    elif [ $ARRAY_LENGTH -eq 0 ]; then   #如果没有记录说明没有网卡
        echo "No available network card!"
        exit 1
    else
        #如果有多条记录则提醒输入选择
        for NIC in ${NIC_IP_ARRAY[*]}; do
            echo $NIC
        done
        while true; do
            read -p "Please enter local use to network card name: " INPUT_NIC_NAME
            COUNT=0
            for NIC in ${NIC_IP_ARRAY[*]}; do
                NIC_NAME=${NIC%:*}
                if [ $NIC_NAME == "$INPUT_NIC_NAME" ]; then
                    NIC=${NIC_IP_ARRAY[$COUNT]%:*}
                    return 0
                else
                   COUNT =1
                fi
            done
            echo "Not match! Please input again."
        done
    fi
}
local_nic

如果有只有一个网卡就不选择。

9、监控LINUX目录和文件变化

利用一个脚本能够实时监控web目录下文件的变化,也就是对该目录的增删改操作都会记录到相应日志下。

主要有两个脚本:

脚本1:将需要监控的目录的原始状态保存到LOG日志 脚本2:将脚本1的原始状态与本脚本比对,如果目录文件发生变化,则将变化的内容保存到日志。

1,监控 /home/www/ 目录改动,并将改动的文件rsync到/home/www3目录

2,监控方法为监控文件的md5值,如果md5值与上次不同,即发生改变

注:原理实际上利用的是du -sb输出值来判断文件的变化,再利用diff进行比对。

1.在执行脚本前要保存原始的状态:

# vi initial.sh

代码语言:javascript复制
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin/:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 监控的目录
DIR=/root
# 临时文件
TMP_A=/tmp/a.txt
# 遍历指定目录下的文件大小及路径并重定向到日志文件
find $DIR -print0 | xargs -0 du -sb  > $TMP_A

2.执行监控脚本 # vi monitor.sh

代码语言:javascript复制
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin/:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# 监控的目录
DIR=/root
# 日期变量
DATE=`date  %F_%H:%M`
# 临时文件
TMP_A=/tmp/a.txt
TMP_B=/tmp/b.txt
TMP_C=/tmp/c.txt
# 日志文件
LOG=/var/log/filemodify.log
# 遍历指定目录下的文件大小及路径并重定向到日志文件
find $DIR -print0 | xargs -0 du -sb  > $TMP_B
# 比较目录变化,并将变化的文件写入日志
DIFF=$(diff $TMP_A $TMP_B)
if [[ -z $DIFF ]];
 then
   echo "Nothing change" >> $LOG
 else
   echo "Here is the change" >> $LOG
   echo "" >> $LOG
   echo "$DIFF" |awk '{print $3}'|sort -k2n |uniq |sed '/^$/d' |tee $TMP_C >> $LOG
   if [ -s $TMP_C ];
     then
       echo "" >> $LOG
       echo "It modified at $DATE" >> $LOG
# 将当前监控的目录结构覆盖为初始状态
       find $DIR -print0 | xargs -0 du -sb  > $TMP_A
   fi
fi
echo "====================================" >> $LOG
#清理临时文件
rm -rf $TMP_B $TMP_C

Shell脚本监控目录内文件改动

代码语言:javascript复制
#! /bin/bash
webroot="/home/www/"
cp /dev/null rsync_file
if [ ! -f file.md5 ];then
  find $webroot -type f -exec md5sum {} ; >>file.md5
else
  for file in $(md5sum -c file.md5|awk -F':' '/FAILED/{print $1}')
    do
      if [ -f $file ];then
      filename_z=$(echo $file|sed 's#/#\/#g')
      sed -i "/ $filename_z/"d file.md5
      md5sum $file >> file.md5
      echo $file >> rsync_file
      else
      echo $file >>rsync_rm
      fi
    done
  for newfile in $(find $webroot -type f)
    do
      grep $newfile file.md5 >/dev/null 2>&1
      if [ $? -gt 0 ];then
      md5sum $newfile >> file.md5
      echo "$newfile" >> rsync_file
      fi
    done
for rfile in $(cat rsync_file)
do
rsync -avzp $rfile /home/www3/
done

10、统计当前目录中以.html结尾的文件总大小

代码语言:javascript复制
方法1:

# find . -name "*.html" -maxdepth 1 -exec du -b {} ; |awk '{sum =$1}END{print sum}'

方法2:

for size in $(ls -l *.html |awk '{print $5}'); do

    sum=$(($sum $size))

done

echo $sum

递归统计:

# find . -name "*.html" -exec du -k {} ; |awk '{sum =$1}END{print sum}'

11、 获取随机字符串或数字

获取随机8位字符串:

代码语言:javascript复制
方法1:

# echo $RANDOM |md5sum |cut -c 1-8

471b94f2

方法2:

# openssl rand -base64 4

vg3BEg==

方法3:

# cat /proc/sys/kernel/random/uuid |cut -c 1-8

ed9e032c

获取随机8位数字:

代码语言:javascript复制
方法1:

# echo $RANDOM |cksum |cut -c 1-8

23648321

方法2:

# openssl rand -base64 4 |cksum |cut -c 1-8

38571131

方法3:

# date  %N |cut -c 1-8

69024815

cksum:打印CRC效验和统计字节

12、获取字符串长度

代码语言:javascript复制
# VAR='hello world!'
# echo $VAR
hello world!
# echo ${#VAR}
12

13、截取字符

截取从offset个字符开始,向后length个字符。

代码语言:javascript复制
截取hello字符串:
# VAR='hello world!'
# echo ${VAR:0:5}
hello
截取wo字符:
# echo ${VAR:6:2}
wo
截取world!字符串:
# echo ${VAR:5}
world!
截取最后一个字符:
# echo ${VAR:(-1)}
!
截取最后二个字符:
# echo ${VAR:(-2)}
d!
截取从倒数第3个字符后的2个字符:
# echo ${VAR:(-3):2}
ld

14、替换字符串

格式:${parameter/pattern/string}

代码语言:javascript复制
# VAR='hello world world!'
将第一个world字符串替换为WORLD:
# echo ${VAR/world/WORLD}
hello WORLD world!
将全部world字符串替换为WORLD:
# echo ${VAR//world/WORLD}
hello WORLD WORLD!

15、定义一个颜色输出字符串函数

方法1:

代码语言:javascript复制
function echo_color() {
    if [ $1 == "green" ]; then
        echo -e "33[32;40m$233[0m"
    elif [ $1 == "red" ]; then
        echo -e "33[31;40m$233[0m"
    fi
}

方法2:

代码语言:javascript复制
function echo_color() {
    case $1 in
        green)
            echo -e "33[32;40m$233[0m"
            ;;
        red)
            echo -e "33[31;40m$233[0m" 
            ;;
        *) 
            echo "Example: echo_color red string"
    esac
}

使用方法:echo_color green "test"

function关键字定义一个函数,可加或不加。

16、打印乘法口诀

代码语言:javascript复制
方法1:
# awk 'BEGIN{for(n=0;n  <9;){for(i=0;i  <n;)printf i"x"n"="i*n" ";print ""}}'
方法2:
for ((i=1;i<=9;i  )); do
   for ((j=1;j<=i;j  )); do
     result=$(($i*$j))
     echo -n "$j*$i=$result "
   done
   echo
done

输入五个100数之内的字符,统计和、最小和最大

代码语言:javascript复制
COUNT=1
SUM=0
MIN=0
MAX=100
while [ $COUNT -le 5 ]; do
    read -p "请输入1-10个整数:" INT
    if [[ ! $INT =~ ^[0-9] $ ]]; then
        echo "输入必须是整数!"
        exit 1
    elif [[ $INT -gt 100 ]]; then
        echo "输入必须是100以内!"
        exit 1
    fi
    SUM=$(($SUM $INT))
    [ $MIN -lt $INT ] && MIN=$INT
    [ $MAX -gt $INT ] && MAX=$INT
    let COUNT  
done
echo "SUM: $SUM"
echo "MIN: $MIN"
echo "MAX: $MAX"

0 人点赞