56.给文件增加内容
57.备份etc目录
58.找出重复的单词
59.人员分组
60.比较两个数大小
给文件增加内容
题目要求
在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:
# This is a test file.
# Test insert line into this file.
核心要点
1.给文档指定行后面增加内容,可以用sed搞定 sed -i ‘5a12345\n56789’ 1.txt
2.比较笨的方法是,依次按顺序打印前5行,然后打印要增加的行,再从文本第6行开使一直到结束依次打印剩余的行。
代码
#!/bin/bash
#这个脚本用来给文件增加行
n=0
cat 1.txt |while read line
do
n=$\[$n+1\]
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
备份etc目录
题目要求
设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式"yymmdd_etc.tar.gz",yy为年,mm为月,dd为日。
核心要点
1.yymmdd用date +%y%m%d表示
2.每月第一天,需要判断date +%d是否是01
代码
#!/bin/bash
#这个脚本用来备份/etc/目录
d1=\`date +%d\`
d2=\`date +%y%m%d\`
if \[ $d1 == "01" \]
then
cd /etc/
tar czf /root/bak/$d2_etc.tar.gz ./
fi
找出重复的单词
题目要求
将文件内所有的单词的重复次数计算出来,只需要列出重复次数最多的10个单词。
核心要点
把非英文的字符删除掉(用空格替换),剩下的就是英文字母或者单词
代码
#!/bin/bash
#这个脚本用来找出重复的单词
for w in \`sed 's/\[^a-zA-Z\]/ /g' $1\`
do
echo $w
done |sort |uniq -c |sort -nr|head #done 后面可以直接用管道
人员分组
题目要求
需求是,把所有的成员平均分成若干个小组。这里,提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结果应该不一致。
核心要点
1.首先确定好要分的小组个数,本题中假设50人,分7个小组,平均每个小组人数应为7
2.为了实现随机性,我们可以根据人名的长度来做一个运算,比如用一个随机数+人名的长度得到一个随机数,然后除以7取余,余数是几就把改用户分到第几组里
3.考虑到人员数量较少,最终分组结果一定不均衡,比如,有的小组疯了10个人,但有的小组却分到了3个人,这样严重不均衡。
4.为了让人员更加均衡,需要把人数偏多的组(大于7的)均分一部分成员到人数偏少的组(小于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
#这个脚本用来给人员分组
#人员列表文件
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 # shuf打乱顺序的命令
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参数的形式提供。
核心要点
浮点数的大小比较
echo "$x>$y" |bc 判断0 和1 , 0是假,1是真
代码
#!/bin/bash
#这个脚本用来比较两个数大小
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