1、要求输入两个参数: 第一个是 目录名称; 第二个是需要查找的单词;
判断所给的目录内,那些目录下是否有yuan.txt文件;
如果目录下有yuan.txt文件,并计算yuan.txt文件里面某个单词的次数;
分析:判断是否两个参数,需要使用 if [ $# -ne 2 ] then echo " " exit fi
也需要判断用户输如的是否是目录: if [ -d $1 ] then cd $1 else echo " " fi
进入这个目录后,使用 for 循环, 并判断 是否是目录,再次判断这个目录下是否存在 yuan.txt这个文件,文件里是否存在root 这个单词, 并打印单词的个数;
for f in `ls .` do if [ -d $f ] then if [-f $f/yuan.txt ] then n=`grep -cw 'root' $f/yuan.txt echi "$1/$f/yuan.txt里面有$n个$2" else echo "木有"
脚本代码如下:
[root@fenye2019 shell]# cat 71.sh
#!/bin/bash
if [ $# -ne 2 ]
then
echo "请输入两个参数"
exit
fi
if [ -d $1 ]
then
cd $1
else
echo "$1目录不存在"
exit
fi
for f in `ls .`
do
if [ -d $f ]
then
if [ -f $f/yuan.txt ]
then
n=`grep -cw "$2" $f/yuan.txt`
echo "$1/$f/yuan.txt里面有$n个$2"
else
echo "$1/$f 下面没有 yuan.txt"
fi
fi
done
执行脚本:
[root@fenye2019 shell]# sh 71.sh /root/ root
/root//pass 下面没有 yuan.txt
/root//python 下面没有 yuan.txt
/root//shell 下面没有 yuan.txt
/root//yuanhh/下面有yuan.txt,该yuan.txt里面有2个root
注释:如上执行结果;
2、打印正方形,交互式脚本,根据用户输入的一个数字作为参考,最终打印出一个正方形;
示例:如果用户输入的数字为 5 ,最终显示的结果如下:
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
分析:因为是交互式脚本:需要使用 read -p 实现: read -p "please input number:" num
用户输入的是否纯数字也要判断; n=`echo $num|sed 's#[0-9]##g'` if [ -n "$n" ] then echo "请输入一个数字" fi
难点在于:如何输入空格和换行,比如用户输入 5 ,那前4个方块后面是空格,第5 个方块后面是换行; echo -n 表示不打印换行;
[root@fenye2019 shell]# for i in `seq 1 3`;do echo "■";done
■
■
■
[root@fenye2019 shell]# for i in `seq 1 3`;do for j in `seq 1 3`; do echo "■";done; done
■
■
■
■
■
■
■
■
■
[root@fenye2019 shell]# for i in `seq 1 3`;do for j in `seq 1 3`; do echo -n "■ ";done; echo ; done
■ ■ ■
■ ■ ■
■ ■ ■
脚本如下:
[root@fenye2019 shell]# cat 72.sh
#!/bin/bash
while :
do
read -p "please input nubmer: " sum
a=`echo $sum|sed 's#[0-9]##g'`
if [ -n "$a" ]
then
echo "请输入一个纯数字"
continue
else
break
fi
done
for i in `seq 1 $sum`
do
for j in `seq 1 $sum`
do
echo -n "■ "
done
echo
done
执行脚本:
[root@fenye2019 shell]# sh 72.sh
please input nubmer: 4
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
3、写一个脚本,依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么;如: hello,root,you uid is 0.
分析:对/etc/passwd 每一行做遍历,截取第一段用户名和第三段 uid,然后格式化输出即可;
第一个方法: 使用 while read line 来逐行输出; cat /etc/passwd|while read line echo $line done
[root@fenye2019 shell]# cat 73.sh
#!/bin/bash
while read line
do
user=`echo $line|awk -F ':' '{print $1}'`
uid=`echo $line|awk -F ':' '{print $3}'`
echo "Hello,$user,your uid is $uid"
done < /etc/passwd
执行脚本:
[root@fenye2019 shell]# sh 73.sh
Hello,root,your uid is 0
Hello,bin,your uid is 1
Hello,daemon,your uid is 2
方法二: awk -F ':' '{print "Hello," $1 ",you uid is " $3"."}' /etc/passwd
[root@fenye2019 shell]# awk -F ':' '{print "Hello," $1 ",you uid is " $3"."}' /etc/passwd
执行脚本:
Hello,nscd,you uid is 28.
Hello,mysql,you uid is 1000.
Hello,php-fpm,you uid is 1001.
注释:可以用awk在 print 时, $1 和 $3 是不需要用双引号引起来的,但是其他字符需要,所有在 { } 里需要用到两对双引号;
4、在linux系统 /home目录下有一个文件test.xml,内容如下:
<configuration>
<artifactItems>
<artifactItem>
<groupId>zzz</groupId>
<artifactId>aaa</artifactId>
</artifactItem>
<artifactItem>
<groupId>xxx</groupId>
<artifactId>yyy</artifactId>
</artifactItem>
<!-- </artifactItem><groupId>some groupId</groupId>
<version>1.0.1.2.333.555</version> </artifactItem>-->
</artifactItems>
</configuration>
用shell脚本删除文件中的注释部分内容,获取文件中所有artifactltem的内容并用如下格式逐行输出;
artifactItem:groupId:artifactId:aaa
分析:这个文件比较特殊,要删除注释部分内容,就是<!--,*-->里的内容;还需要分如下两种情况考虑;
当注释行在一行时: 用 sed 删除 sed 's/<!--.*-->/d' test1.xml
[root@fenye2019 shell]# cat test1.xml
yuanfenye
<!-- dsfsdfkj;ljfskd -->
[root@fenye2019 shell]# sed '/<!--.*-->/d' test1.xml
yuanfenye
如果注释不在一行,需要得到 <!-- 和 --> 所在的行号,然后用 sed 'n1,n2'd 删除;
脚本代码如下:
[root@fenye2019 shell]# cat 74.sh
#!/bin/bash
sed '/<!--.*-->/d' test.xml > test2.xml
egrep -n '<!--|\-\->' test2.xml |awk -F ':' '{print $1}' > /tmp/line_number1.txt
n=`wc -l /tmp/line_number1.txt|awk '{print $1}'`
n1=$[$n/2]
for i in `seq 1 $n1`
do
j=$[$i*2]
k=$[$j-1]
x=`sed -n "$k"p /tmp/line_number1.txt`
y=`sed -n "$j"p /tmp/line_number1.txt`
sed -i "$x,$y"d test2.xml
done
grep -n 'artifactItem>' test2.xml |awk '{print $1}' |sed 's/://' > /tmp/line_number2.txt
n2=`wc -l /tmp/line_number2.txt|awk '{print $1}'`
get_value(){
sed -n "$1,$2"p test2.xml|awk -F '<' '{print $2}'|awk -F '>' '{print $1,$2}' > /tmp/value.txt
cat /tmp/value.txt|while read line
do
x=`echo $line|awk '{print $1}'`
y=`echo $line|awk '{print $2}'`
echo artifactItem:$x:$y
done
}
n3=$[$n2/2]
for j in `seq 1 $n3`
do
m1=$[$j*2-1]
m2=$[$j*2]
nu1=`sed -n "$m1"p /tmp/line_number2.txt`
nu2=`sed -n "$m2"p /tmp/line_number2.txt`
nu3=$[$nu1+1]
nu4=$[$nu2-1]
get_value $nu3 $nu4
done
执行脚本:
[root@fenye2019 shell]# sh 74.sh
artifactItem:groupId:zzz
artifactItem:artifactId:aaa
artifactItem:groupId:xxx
artifactItem:artifactId:yyy
5、使用条件函数 if 写一个shell函数,实现以下功能:
当/root/yuanhh 目录存在时将/root目录下所有txt结尾的文件或目录移到/root/yuanhh目录;
当/root/yuanhh目录不存在时,创建该目录,然后退出;
分析:需要判断/root/yuanhh 目录是否存在: if [ -d /root/yuanhh ]
查找以txt结尾的文件: find /root/ -type f -name "*.txt"|xargs -i mv {} /root/yuanhh/
脚本代码如下:
[root@fenye2019 ~]# cat 75.sh
#!/bin/bash
f_judge()
{
if [ -d $1 ]
then
find /root/ -type f -name "*.txt"|xargs -i mv {} /root/yuanhh
#find /root/ -type f -name "*.txt" -exec mv {} /root/yuanhh \;
else
mkdir $1
fi
}
f_judge /root/yuanhh
执行脚本:
[root@fenye2019 ~]# ls
1.txt 2.txt 3.txt
[root@fenye2019 ~]# sh 75.sh #第一次执行;多了yuanhh目录;
[root@fenye2019 ~]# ls
1.txt 2.txt 3.txt yuanhh
[root@fenye2019 ~]# sh 75.sh #第二次执行;移动到yuanhh目录下;
[root@fenye2019 ~]# ls yuanhh/
1.txt 2.txt 3.txt test.txt
注释:执行后结果如下;