shell练习题

1.awk 计算1到100的和
awk ‘BEGIN { for(i=1; i<=100; i++) sum+=i; print sum}’

for(i=1;i<=100;i++); 单单这个语句的话……做100个空循环,因为FOR循环体为空。 先是i=1, 再是看i是否小于等于100,如果满足这个条件,那么({什么也不做},i++),进行下一轮循环。 如果不满足,跳出这个循环。

2.sed删除某关键字的下一行到最后一行
[root@test200 ~]# cat test
a
b
c
d
e
f
[root@test200 ~]# sed ‘/c/{p;:a;N;$!ba;d}’ test
a
b
c

定义一个标签a,匹配c,然后N把下一行加到模式空间里,匹配最后一行时,才退出标签循环,然后命令d,把这个模式空间里的内容全部清除。

if 匹配”c”
:a
追加下一行
if 不匹配”$”
goto a
最后退出循环,d命令删除。
3.编写一个shell脚本,利用for循环将当前目录下的.txt文件移动到指定的目录,并按文件大小显示出移动后指定的目录的内容。

#/bin/bash
for name in ls *.txt
do
if [ ! -d ./file_txt ] ;
then
mkdir ./file_txt
fi
cp ${PWD}/$name ./file_txt
done
ls -Sl

说明:
! -d ./file_txt意思是./file_txt不是目录的话,判断条件为真。
ls -Sl 从大到小排序,ls -Slr从小到大排序。

4.查找当前目录创建时间大于10天的文件,然后删除。
find . mtime +10 |xargs rm -rf

or

find . mtime +10 -exec rm -rf {} \;

说明:
-exec 与 \;是固定格式

5.每三行变一行
比如1.txt内容
1
2
3
4
5
6
7

处理后应该是
1 2 3
4 5 6
7

sed ‘N;N;s/\n/ /g’ 1.txt

说明:
sed以行为单位处理文本,其模式缓冲区内只保留一行内容待处理。
N命令,将下一行读入并附加到当前行后面,以 \n (换行符)分隔,一起存在模式缓冲区内。
s/\n/ /g 为将换行符替换为空格,即删除换行符

\n 就表示换行符

6.批量创建用户脚本练习题
用脚本批量创建用户user_00 … user_20, 并且给这些用户设置一个随机密码,并记录到一个日志文件中。

#!/bin/bash
for i in seq -w 0 20
do
useradd user_$i
passwd=mkpasswd -s 0
echo $passwd |passwd –stdin user_$i
echo “user_$i $passwd” >> /tmp/pass.log
done

7.打印乘法口诀

#!/bin/bash
##by xingcheng 打印乘法口诀表
##2016/8/12
for i in seq 1 9
do
for j in seq 1 9
do
k=$(($i*$j))
echo -n $k
done
echo
done

说明:
echo -n 不换行输出

8.for循环脚本练习题
写一个脚本,把当前目录下的目录(只需要一级)列出来。

#!/bin/bash
##by xingcheng
#2016/8/12
for i in ls
do
if [ -d $i]
then
echo $i
fi
done

说明:
shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。
-e :判断文件或目录是否存在
-d :判断是不是目录,并是否存在
-f :判断是否是普通文件,并存在
-r :判断文件是否有读权限
-w :判断文件是否有写权限
-x :判断文件是否可执行
使用if判断时,具体格式为:
if [ -e filename ] ; then
9.用while循环实现每隔10秒钟执行一次w命令。
#!/bin/bash
while:
do
w
sleep 10
done

说明:
当循环条件为:时,表示死循环(while:)。
while循环格式为:
while 条件;do
command
done

10.#!/bin/bash
##2016/8/12
curdate=date +%Y%m%d_date +%H%M%S
dir=ROOT_${curdate}
mkdir ${dir}
cd ${dir}

说明:
cd ${dir}的实现是在虚拟空间,并不在当前shell。所以并不会更改当前路径。

11.写一个脚本用来互换两个文件的文件名。
#!/bin/bash/
##by xingcheng
##2016/8/12
exch_name() {
/bin/mv $1 /tmp/tmp
/bin/mv $2 $1
/bin/mv /tmp/tmp $2
}

exch_name file1 file2

12.请按照这样的日期格式(xxxx-xx-xx)每日生成一个文件,例如今天生成的文件为2013-09-23.log, 并且把磁盘的使用情况写到到这个文件中。

#! /bin/bash
d=date +%F
logfile=$d.log
df -h > $logfile

然后再增加一条每日定点执行的任务计划即可

13.想办法把文档中只有一个数字的行打印出来
如题: grep sed awk 亦或是shell,只要能达到我们的需求就ok。

#!/bin/bash
f=/etc/passwd
line=wc -l $f|awk '{print $1}'
for l in seq 1 $line; do
n=sed -n "$l"p $f|grep -o '[0-9]'|wc -l;
if [ $n -eq 1 ]; then
sed -n “$l”p $f
fi
done
13.1.设定变量FILE的值为/etc/passwd
2.依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么
形如:(提示:LINE=wc -l /etc/passwd | cut -d" " -f1)
Hello,root,your UID is 0.
3.统计一个有多少个用户

#!/bin/bash
##by xingcheng
##2016/8/13
LINE=wc -l /etc/passwd | cut -d" " -f1
for I in seq 1 $LINE;do
userid=sed -n ${I}p /etc/passwd |awk -F ':' '{print $3}'
username=sed -n ${I}p /etc/passwd |awk -F ':' '{print $1}'
echo “Hello,$username,you UID is $userid”
done
echo “They are $LINE users”
说明:
wc -l:统计多少行数seq 1 $LINES:1-多少行
passwd文件格式:username:password:uid:gid:allname:homedir:shell
用户名:密码:用户ID:组ID:用户全名:主目录:登录shell

14.
写一个交互脚本,实现这样的需求: 不加任何选项直接运行脚本后,会出现提示:
请选择一个数字:
1: 重启httpd服务
2: 重启mysqdl服务
3: 重启vsftpd服务
加选项 –httpd 会重启httpd服务,加 –mysql会重启mysqld服务,加–ftp会重启vsftpd服务
#!/bin/bash
##by xingcheng
##2016/8/15
echo “Please choose the number you want to restart the service:”
read -p “1:restart httpd 2:restart mysqld 3:restart vsftpd” I

case $I in
1)
service httpd restart
;;
2)
serivce mysqld restart
;;
3)
service vsftpd restart
;;
*)
echo “Do not have this service”
;;
esac
15.有一列数字如下:
第1次:1
第2次:2
第3次:3
第4次:5
第5次:8
第6次:13
第7次:21
第8次:34
第9次:55
第10次:89
第11次:144
写出100次的数是什么。

脚本一:
#!/bin/bash
##by xingcheng
##2016/8/15
i=1
j=2
h=3
while :
do
if [ $h -gt 100 ]
then
echo “$sum”
exit
else
sum=$[$i+$j]
h=$[$h+1]
i=$j
j=$sum
fi
done
脚本二:
#!/bin/bash
# Author: Maria.
# Date & Time: 2016-02-28 14:30:05
# Description: Please Edit here.
a=1
b=2
for((i=3;i<=100;i++))
do
c=$[$a+$b]
a=$b
b=$c
done
echo $c

脚本三;
#!/bin/bash
# Author: Maria.
# Date & Time: 2016-02-28 14:39:14
# Description: Please Edit here.
a[1]=1
a[2]=2
i=3
while [ $i -le 100 ]
do
((a[$i]=${a[$i-1]}+${a[$i-2]}))
((i++))
done
echo ${a[100]}

说明:
实际上由于整形长度的限制,计算会出现错误,大约到92次的时候由于整形长度限制,会产生负数,所以最后的结果比实际结果要小,用这个脚本计算的结果是1298777728820984005,实际结果应该是573147844013817084101

16.用while实现1到10所有数字相加求和。
#!/bin/bash
##by xingcheng
##2015/8/15
a=0
sum=0
while [ $a -le 10 ]
do
sum=$[$a+$sum]
a=$[$a+1]
done
echo “$sum”

17.
写一个脚本产生随机3位的数字,并且可以根据用户的输入参数来判断输出几组。 比如,脚本名字为 number3.sh。
执行方法:
bash number3.sh
直接产生一组3位数字。
bash number3.sh 10
插上10组3位数字。
思路: 可以使用echo $RANDOM获取一个随机数字,然后再除以10,取余获取0-9随机数字,三次运算获得一组。
http://www.apelearn.com/bbs/thread-10556-1-1.html
方法一:
#!/bin/bash
##by xingcheng
##2015/8/15
read -p “Please enter you want to get a set of numbers” I
while [ $I -gt 0 ]
do
a=$[$RANDOM%10]
b=$[$RANDOM%10]
c=$[$RANDOM%10]
I=$[$I-1]
echo $a$b$c
done

方法二:
#!/bin/bash
get_a_num() {
n=$[$RANDOM%10]
echo $n
}

get_numbers() {
for i in 1 2 3; do
a[$i]=get_a_num
done
echo ${a[@]}
}

if [ -n “$1” ]; then
m=echo $1|sed 's/[0-9]//g'
if [ -n “$m” ]; then
echo “Useage bash $0 n, n is a number, example: bash $0 5”
exit
else
for i in seq 1 $1
do
get_numbers
done
fi
else
get_numbers
fi

18.
bash for循环打印下面这句话中字母数不大于6的单词。
Bash also interprets a number of multi-character options.
for s in Bash also interprets a number of multi-character options
do
n=echo $s|wc -c
if [ ! $n -gt 6 ]
then
echo $s
fi
done
19.创建文件1.txt,内容如下。
Red Hat Enterprise Linux Version 5.3
Get the latest news about the world’s Open Source Leader
Red Hat Network
Manage your system dffectively through Red Hat Network
Global Learning Services
You’ve got Red Hat Enterprise Linux,now get the skills
check out Red Hat’s training courses and industry-acclaimed
2009082301
#This is a test456 line
space test123 line234
1.编写一个awk脚本,功能是打印所有行
2.编写一个awk脚本,打印文件第八行
3.用awk命令打印文件所有行的第一个字段
4.打印输入行总数
5.打印每行字段数
6.打印最后一行
7.打印字段数多于4个的行
8.打印文件所有字段的总数
9.打印3-8行
10.在文件顶部加上标题“Document”
11.隔行删除(1,3,5,…行删除)
12.查找system替换成***SYSTEM***
1.awk ‘{print $0}’ 1.txt
2.awk ‘NR==8 {print $0}’ 1.txt
3. awk ‘{print $1}’ 1.txt
4. awk ‘END{print NR}’ 1.txt
5. awk ‘{print NF}’ 1.txt
6. awk ‘END {print $0}’ 1.txt
7. awk ‘NF>4 {print $0}’ 1.txt
8. awk ‘{sum=sum+NF} END{print sum}’ 1.txt
9. awk ‘NR>=3 && NR<=8 {print $0}’ 1.txt
10. awk ‘BEGIN{print “Document”} {print $0}’ 1.txt
11. awk ‘NR%2==0 {print $0}’ 1.txt
12. awk ‘gsub(“system”,”SYSTEM”,$0) {print $0}’ 1.txt

20.
awk使用gsub函数替换字符串

gsub(/123/,456,$3)将第三个域中的“123”替换成“456”
例子:
test文件内容:
0001|efskjfdj|EREADFASDLKJCV
0002|djfksdaa|JDKFJALSDJFsddf
0003|efskjfdj|EREADFASDLKJCV
0004|djfksdaa1234|JDKFJALSDJFsddf

将文本以“|”分割,将第二域中的字母“d”替换成“#”
awk -F ‘|’ ‘gsub(/d/,”#”,$2) {print $0}’ test
0001 efskjf#j EREADFASDLKJCV
0002 #jfks#aa JDKFJALSDJFsddf
0003 efskjf#j EREADFASDLKJCV
0004 #jfks#aa1234 JDKFJALSDJFsddf

21.用 AWK 怎样区分一个字段是 数字 还是 汉字?
如:files1
上|123.00|123|555|4554|
在|123.00|123|555|4554|
1|123.00|123|555|4554|
2|123.00|123|555|4554|
9|123.00|123|555|4554|
是|123.00|123|555|4554|

如何将 $1 = 数字 的区分出来!!

awk ‘/^[0-9]/{print}’ 2.txt

awk -F ‘|’ ‘$1~/[0-9]/ {print $1}’ 2.txtD

22.从1到100的数能被3整除的所有数字的和相加
for I in seq 1 100
do
K=$[$I%3]
if (($K==0))
then
sum=$[$sum+$I]
fi
echo $sum
done

说明:
if(($K==0))
或者 if [ $k -eq 0 ]
编写一个日志轮询归档脚本
类似于日志切割,系统有个logrotate程序,可以完成归档。但现在我们要自己写一个shell脚本实现归档。 举例: 假如服务的输出日志是1.log,我要求每天归档一个,1.log第二天就变成1.log.1,第三天1.log.2, 第四天 1.log.3 一直到1.log.5。
下面是我的一个参考脚本,供大家参考:
#!/bin/bash
function e_df()
{
[ -f $1 ] && rm -f $1
}

for i in seq 5 -1 2
do
i2=$[$i-1]
e_df /data/1.log.$i
if [ -f /data/1.log.$i2 ]
then
mv /data/1.log.$i2 /data/1.log.$i
fi
done

e_df /data/1.log.1
mv /data/1.log /data/1.log.1

#!/bin/bash
##by xingcheng
##2016/8/16

I
for I in “seq 1 5″
19.写一个脚本:要求如下:
1:依次向/etc/passwd目录中的每一个用户问好,并指出其UID号!(eg:HELLO,root,your uid is 0)
2:统计这个脚本共有多少个账户?

#!/bin/bash
FILE=”/etc/passwd”
for l in cat $FILE ; do
username=echo $l | awk -F ':' '{print $1}'
userid=echo $l | awk -F ':' '{print $3}'
echo “HELLO,$username your UID is $userid”
done
d=wc -l $FILE
echo ” There are $d users”

20.web服务器上有个目录,它的结构是这样的,首先有256个一级子目录和一个特殊目录,另外这256个一级子目录下还有256个二级子目录(特殊目录除外)。在这些二级子目录下有很多小文件,而且是每时每刻都会生成很多个。 虽然文件不大,但是时间长了,逐渐发现该分区的下inode快被占用满了。 所以请写一个小脚本,实现每天删除两天前的小文件,注意忽略那个特殊的一级子目录default。

目录: /data/web/abc/
二/三级子目录: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de default df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff (三级子目录下没有default目录)

#! /bin/bash
cd /data/web/abc
for f in ls |grep -v default; do
for f1 in ls $f; do
find $f/$f1 -type f -mtime +2|xargs rm -f
done
done
21.设计一个shell脚本来备份数据库,首先在本地服务器上保存一份数据,然后再远程拷贝一份,本地保存一周的数据,远程保存一个月。
假定,我们知道mysql root账号的密码,要备份的库为discuz,本地备份目录为/bak/mysql, 远程服务器ip为192.168.123.30,远程提供了一个rsync服务,备份的地址是 192.168.123.30::backup . 写完脚本后,需要加入到cron中,每天凌晨3点执行。

#! /bin/bash
### backup mysql
### Writen by Aming.

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/texlive/2012/bin/i386-linux:/usr/local/mysql/bin:/usr/local/mysql/bin:/root/bin
d1=data +%w
d2=date +%d
pass=”your_mysql_password”
bakdir=/bak/mysql
r_bakdir=192.168.123.30::backup

exec 1>/var/log/mysqlbak.log 2>/var/log/mysqlbak.log

echo “mysql backup begin at date +"%F %T".”
mysql -uroot -p$pass –default-character-set=gbk discuz >$bakdir/$d1.sql
rsync -a $bakdir/$d.sql $r_bakdir/$d2.sql
echo “mysql backup end at date +"%F %T".”

然后加入cron
0 3 * * * /bin/bash /usr/local/sbin/mysqlbak.sh

未经允许不得转载: » shell练习题
微信公众号:这是个测试
关注我们,每天分享更多有趣的事儿,有趣有料!
12000人已关注
分享到:
赞(0) 打赏

相关推荐

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏