常用shell实例收集

新增:

处理文件

a 1

a 2

b 3

c 4

转变成

a 1 2

b 3

c 4

#!/bin/bash
uniq=`cat a.txt| awk '{print $1}' | sort | uniq`
for item in $uniq
do
    line=`cat a.txt | grep $item | awk -v item=$item 'BEGIN{count="";}{if($1==item){count=(count" "$2);}}END{print item, count}'`
    echo $line >> b.txt
done

处理成

a 3

b 3

c 4

#!/bin/bash
src=$1
dst=$2
uniq=`cat $src | awk '{print $1}' | sort | uniq`
for host in $uniq
do
    line=`cat $src | grep $host | awk -v host=$host 'BEGIN{count=0;}{if($1==host){count+=$2;}}END{if(count!=0) print host, count}'`
    echo $line >> $dst
done


上述两个例子都可以用一句awk搞定

cat a.txt | awk '{a[$1]=(a[$1]" "$2)}END{for (i in a) print i,a[i];}'


打乱sort后的文本顺序

while read i;do echo "$i $RANDOM";done<file.txt|sort -k2n| awk '{print $1}'

读取文件后缀

echo ${$file##*.}



1.查找当前目录中所有大于500M的文件,把这些文件名写到一个文本文件中,并统计其个数。

find ./ -size +500M -type f | tee file_list | wc -l

还可使用c,k.注意输出为./xxx.file,如果要使用文件名,去掉前两个字符。find ./ -size +100c -exec basename {} \;

查找文件夹下所有.c文件并拷贝到另一文件夹下

find ./ -name *.c | xargs -i cp {} test

2.在目录/tmp下找到100个以abc开头的文件,然后把这些文件的第一行保存到文件new

for filename in `find /tmp -type f -name "abc*"|head -n 100`
do
sed -n '1p' $filename>>new
done

3.把文件b中有的,但是文件a中没有的所有行,保存为文件c,并统计c的行数。

grep -xvf a b | tee c | wc -l                      grep –f a.txt b.txt
自己试试grep -f 的用法吧 -v是取反


4.判断一文件是不是块或字符设备文件,如果是将其拷贝到 /dev 目录下

read -p "input a file:" filename
if [ -b $filename -o -c $filename ]
then
    cp $filename /dev/
fi

5. 每隔 10 分钟监控一次,监控 /usr 下如果大于 5G ,发邮件给管理员

#!/bin/bash
while true
do
    sleep 600
    n=$(du -s /usr | cut -f1)
    if [ $n -gt 5242880 ]
    then
        mail -s "greater" [email protected] < ~/filename #将文件filename的内容发送出去。
    fi
done
最好判断root权限, 在脚本中加入

if [ $(id -u) != "0" ]; then
    printf "Error: You must be root to run this script!\n"
    exit 1
fi

6. a.log 文件中提取包含 "WARNING" "FATAL" ,同时不包含 "IGNOR" 的行,然后提取以 ":" 分割的第 5 个字段

grep -E 'WARNING|FATAL' a.log | grep -v 'IGNOR' | awk -F ":" '{print $5}'

7. 编写一个脚本,进行简单的减法运算,要求提示输入变量

#!/bin/bash
read -p "input a number:" num1
read -p "input another number:" num2
let "num3=num1-num2"
echo $num3

8. 把某个目录下的文件扩展名改为 bat ,再以时间为文件名压缩打包存放到某个目录。

#!/bin/bash
for file in $(ls $1)
do
    new_file=${file%.*}.bat
    mv ./$1/$file ./$1/$new_file
    tmp=$(date +%y)
    tar cvf ./$tmp.tar ./$1
done

9. 从网上下载一个文件,保存到指定目录

#!/bin/bash
url=http://rs1.bn.163.com/ent/2009/05/20_canquedege.wma
dir=~/下载
wget -P $dir $url

10. 判断一个数是不是完数。打印出 1-1000 之间的完数。 完数就是约数的和等于自身 2 倍的数。 (6,28,496)

#!/bin/bash
sub()
{
    i=1;
    sum=0;
    while [ $i -le $num ]
    do
        let "m=num%i"
        if [ $m -eq 0 ]
        then
            let "sum=sum+i"
        fi
        let "i=i+1"
    done
    let "a=2*num"
    if [ $a -eq $sum ]
    then
        echo $num
    fi
}
num=1
while [ $num -le 1000 ]
do
    sub
    let "num = num+1"
done

11. 以行为单位,求文件 A 和文件 B 交集,并集,差集。

并:
sort -m <(sort A | uniq) <(sort B | uniq) | uniq
交:
sort -m <(sort A | uniq) <(sort B | uniq) | uniq -d
差:
sort -m <(sort A | uniq) <(sort B | uniq) <(sort B | uniq) | uniq -u

12. 在某个文件夹下查找含有指定字符串的文件

#!/bin/bash
for file in $(ls $2)
do
    bname=$(grep -l $1 $2/$file)
    basename $bname
done
调用方法:./tst 000 bash#在文件夹bash中查找含有“000”的文件。


13.添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx0130

#!/bin/bash
groupadd class1
for i in {9901..9930}
do
    xx=$(echo $i | sed 's/99//');
    useradd -g class1 std$xx -p ""
done

14. 实现自动删除 50 个账号的功能。账号名为 stud1 stud50
#!/bin/bash
i=0
while [ i -le 50 ]
do
   let i++
       userdel -r stud$i
done

15. 某系统管理员需每天做一定的重复工作,请按照下列要求,编制一个解决方案:
1 )在下午 4 :50 删除 /abc 目录下的全部子目录和全部文件;
2 )从早 8:00 ~下午 6:00 每小时读取 /xyz 目录下 x1 文件中每行第一个域的全部数据加入到 /backup 目录下的 bak01.txt 文件内;
3 )每逢星期一下午 5:50 /data 目录下的所有目录和文件归档并压缩为文件: backup.tar.gz
4 )在下午 5:55 IDE 接口的 CD-ROM 卸载(假设: CD-ROM 的设备名为 hdc );
5 )在早晨 8:00 前开机后启动。

vim /etc/crontab 在里面增加下面内容:
1)50 16 * * * root rm -rf /abc/* 2>&1 &
2)00 8-18 * * * root cat /xyz/x1|awk '{print $1}' >> /backup/bak01.txt 2>&1 &
3)50 17 * * 1 root cd /data;tar -zcvf backup.tar.gz * 2>&1 &
4)55 17 * * * root umount /hdc 2>&1 &
5)在早晨8:00前开机后启动 --> 这个我不是很明白它的意思,不知道是不是8点前开机就启动上面的设定,8点后才开机就不用启动的意思。姑且用下面这个命令吧。
chkconfig --level 2345 crond on


16. 设计一个 shell 程序,在每月第一天备份并压缩 /etc 目录的所有内容,存放在 /root/bak 目录里,且文件名
为如下形式 yymmdd_etc yy 为年, mm 为月, dd 为日。 Shell 程序 fileback 存放在 /usr/bin 目录下。

vim /usr/bin/fileback.sh
#!/bin/bash
#fileback.sh
#file executable: chmod 755 fileback.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
filename=`date +%y%m%d`_etc.tar.gz
cd /etc/
tar -zcvf $filename *
mv $filename /root/bak/
------------------------------------------------------
vim /etc/crontab 加入
* * 1 * * root ./fileback.sh &

17. 有一普通用户想在每周日凌晨零点零分定期备份 /user/backup /tmp 目录下,该用户应如何做?
首先说一下非 root 用户编写 crontab 文件的方法。

一:
[sword@localhost ~]$ vim cronfile 
[sword@localhost ~]$ crontab cronfile 
二:
[sword@localhost ~]$ crontab -e
no crontab for sword - using an empty one
crontab: installing new crontab
查看结果:
[root@localhost cron]# crontab -u sword -l
显示内容是:/var/spool/cron/sword 文件的内容。
vim ~/shit.sh
#!/bin/bash
cp /user/backup/* /tmp/
--------------------------------------------
crontab -e
0 0 * * 0 ~/shit.sh &

18. 设计一个 Shell 程序,在 /userdata 目录下建立 50 个目录,即 user1 user50 ,并设置每个目录的权限,其
中其他用户的权限为:读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行。

#!/bin/bash
for ((i=1;i<=50;i++))
do
       mkdir -p/usrdata/user$i
       cd /usrdata
       chmod 754 user$i
done

19. 一个shit.txt文件内容全部是类似
202.205.151.21 -- 23 59 22 -“HTTP GET”-“Mozila”
...
写一个 SHELL 命令找出最多的 10 IP

awk -F "--" '{print $1}' shit.txt | sort | uniq -c | sort -r | sed -n '1,10p'


20./tmp 路径下有 800 个文件 , 文件名的格式是 :filename_YYYYMMDD_ 序列号 ( 001 999).dat, 例如 :filename_20040108_089.dat 。现在想把这些文件改名 , 新文件名的格式是 :filename_TODAY( 当前日期 )_ 序列号 ( 500 开始 , 到达 999 之后从 001 开始 ).dat, 例如 : filename_20040108_089.dat 改为 filename_20041222_589.dat, 注意新文件名的序列号的顺序需要和原来的一致 , 即要做排序处理。

#!/usr/bin/bash
DEST_FILE_PART2="_`date '+%Y%m%d'`_"
EXT_NAME=".dat"
SRC_FILE_LIST=`find /tmp -name "*_*_*$EXT_NAME" -print`
for each in $SRC_FILE_LIST; do
    DEST_FILE_PART1=`echo $each | awk -F"_" '{print $1}'`
    OLD_NUM=`echo $each | awk -F"_" '{print $3}' | awk -F"." '{print $1}'`
    DEST_FILE_PART3=`expr $OLD_NUM + 500`
    [ $DEST_FILE_PART3 -gt 999 ] && DEST_FILE_PART3=`expr $OLD_NUM - 499`
        && DEST_FILE_PART3=`printf %03d $DEST_FILE_PART3`
    DEST_FILE=$DEST_FILE_PART1$DEST_FILE_PART2$DEST_FILE_PART3$EXT_NAME
    echo "mv $each to $DEST_FILE"
    mv $each $DEST_FILE
done

我的解法

#!/bin/bash
new_file=$(date +20%y%m%d);
for file in $(ls ~/bash)
do
    i=$(echo "$file" | sed 's/.*_[0-9]*_\([0-9]*\).dat/\1/')    #取出序列号
    i=$(echo $i | sed 's/^0*\([0-9]*\)/\1/')                #去掉序列号前面可能的 ‘0’,
    let "ii=i+500"
    if [ $ii -gt 999 ]
    then
        let "ii=ii-999"
    fi
    ii=`printf %03d $ii`                            #添上可能需要的‘0’
    update=$(echo "$file" | sed 's/\(.*\)_[0-9]*_[0-9]*.dat/\1_'$new_file'_'$ii'.dat/')
    mv ~/bash/$file ~/bash/$update
done

你可能感兴趣的:(常用shell实例收集)