题目要求

在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:

# This is a test file.
# Test insert line into this file.

参考答案

sed  -i '5a# This is a test file.\n# Test insert line into this file.'
#!/bin/bash
#这个脚本用来给文件增加行
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

#计数开始
n=0
cat 1.txt |while read line
do
    n=$[$n+1]
    #当n为5时开始,将增加的行增加进去 
    if [ $n -eq 5 ]
    then
        echo $line
    echo -e "# This is a test file.\n# Test insert line into this file."
    else
    echo $line
    fi
done

题目要求

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

参考答案

#!/bin/bash
#这个脚本用来备份/etc/目录
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02

#第一个时间用来判断是不是每月特定的那天
d1=`date +%d`
#第二个时间用来作为压缩后文件名
d2=`date +%y%m%d`
#每月01号时开始压缩
if [ $d1 == "01" ]
then
    cd /etc/
    tar czf /root/bak/$d2_etc.tar.gz ./
fi

题目要求

将文件内所有的单词的重复次数计算出来,只需要列出重复次数最多的10个单词。

参考答案

#!/bin/bash
#这个脚本用来找出重复的单词
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02
#将文件中非字母的字符全部置空
for w in `sed 's/[^a-zA-Z]/ /g' $1`
do
    echo $w
done |sort |uniq -c |sort -nr|head

题目要求

需求是,把所有的成员平均分成若干个小组。这里,提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结果应该不一致。

参考人员名单

xiaoguisheng
guoyuqing
xiongyongzheng
mengjintang
chaizuzhou
zhousheng
xufangming
zhaoliangyun
hanshiru
wangxianyi
zhangjipei
luxiuli
yangshugen
guoyongzhi
lijianguo
wuqiongchen
dinglin
yaoyashan
yinzijia
wangbencheng
liuxiuwen
chenzuqi
leyuguo
baozongyao
fenghao
sunxiaoquan
zhangyaxian
lijiuzhe
dulichun
lixi
shenpeiwen
zousilin
luoping
chaiyan
fandaozhang
huzixiang
jinzhen
zhujunfeng
liqianbiao
hangyanliang
luorenjian
loujianji
fujianzhou
gengyiwu
jinjigui
liuzhizhong
lisanyan
lisili
zhangyiyu
songguozhen
zhangxinghua
zhaozhiyong
huanghe
xiaojie
fanhongfei
wangguiwen
renshumin
songfuying
zhanghaibo
liguangqun
puaihua
yanzhihua
gaojixian
liulai
funing
chenruizhi
chendaxin
laishaoying
xujian
xiaozhekou
xuxiaping
jiangchunqing

参考答案

#有点小复杂需要慢慢消化 

#!/bin/bash
#这个脚本用来给人员分组
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-02

#人员列表文件
f=member.txt
#小组数
group_n=7
#人员总数
member_n=`wc -l $f|awk '{print $1}'`

#根据姓名计算该用户所在小组的id
get_n()
{
    #根据姓名计算cksum值
    l=`echo $1|cksum|awk '{print $1}'`
    #获取一个随机数
    n1=$RANDOM
    #cksum值和随机数相加,然后除以小组数取余,这样可以确保每次获取到的余数都不一样
    n2=$[$n1+$l]
    g_id=$[$n2%$group_n]
    #假如小组数为7,则余数范围0-6,如果余数为0,则小组为7
    if [ $g_id -eq 0 ]
    then
        g_id=$group_n
    fi
    echo $g_id
}

for i in `seq 1 $group_n`
do
    #n_$i.txt为临时文件,用来记录该小组内的成员
    #脚本之前执行过,则该文件会存在,本次执行脚本前应该删除掉这个临时文件
    [ -f n_$i.txt ] && rm -f n_$i.txt
done

shuf $f|while read name
do
    #计算用户所在小组的id
    g=`get_n $name`
    #将人员追加写入到他对应的小组里
    echo $name >> n_$g.txt
done

#定义计算文件行数的函数
nu(){
    wc -l $1|awk '{print $1}'
}

#获取组员人数最多的小组
max(){
    ma=0
    for i in `seq 1 $group_n|shuf`
    do
        n=`nu n_$i.txt`
        if [ $n -gt $ma ]
        then
            ma=$n
       fi
    done
    echo $ma
}

#获取组员人数最少的小组
min(){
    mi=$member_n
    for i in `seq 1 $group_n|shuf`
    do
       n=`nu n_$i.txt`
       if [ $n -lt $mi ]
       then
           mi=$n
       fi
    done
    echo $mi
}

#定义四舍五入函数
div()
{
    n=`echo "scale=1;$1/$2"|bc`
    n1=`echo "scale=1;$n+0.5"|bc`
    echo $n1|cut -d. -f1
}

#小组组员平均值(非四舍五入)
ava_n=$[$member_n/$group_n]
#小组组员平均值(四舍五入)
ava_n1=`div $member_n $group_n`

if [ $ava_n -eq $ava_n1 ]
then
    #定义初始最小值
    ini_min=1
    #以下while循环要做的事情,就是要把人数多的组里的人搞到人数少的组里去
    #此while循环的条件是,当人数最少的组成员数小于组员平均值
    while [ $ini_min -lt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
            #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一个人名
        name=`tail -n1 $f1`
        #将这个人名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_min=`min`
    done
else
    #定义初始最大值
    ini_max=$member_n
    while [ $ini_max -gt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
                #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一个人名
        name=`tail -n1 $f1`
        #将这个人名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_max=`max`
    done
fi

for i in `seq 1 $group_n`
do
    echo -e "\033[34m$i 组成员有:\033[0m"
    cat n_$i.txt
    #把临时文件删除
    rm -f n_$i.txt
    echo
done

写一个shell脚本,比较两个数的大小,支持浮点数,两个数通过shell参数的形式提供。

参考答案

#!/bin/bash
#这个脚本用来比较两个数大小
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-05

if [ $# -ne 2 ]
then
    echo "请提供两个参数."
    exit
fi

#判断函数是否合法及一些特殊情况
if_number() 
{
    if echo $1|grep -q '^-'
    then
    nu=`echo $1|sed 's/^-//'`
    else
    nu=$1
    fi
    n=`echo $nu|sed 's/[0-9.]//g'`
    if [ -n "$n" ]
    then
    echo "$1不是合法数字."
    exit
    fi
    if echo $1|grep -q '^\.'
    then
    echo "$1不是合法数字."
    exit
    fi
}

if_number $1
if_number $2

n1=`echo "$1>$2"|bc`
if [ $n1 -eq 1 ]
then
    echo "$1 > $2"
else
    if [ "$1" == "$2" ]
    then
    echo "$1 = $2"
    else
    echo "$1 < $2"
    fi
fi