shell实例100例《四》

注意  :     在VIM中使用set paste格式化vim,再粘贴内容,格式就不会乱

3cc735df81ac0957008890e6751b67911ce.jpg

关系运算符

运算符说明举例
-eq检测两个数是否相等,相等返回 true[ $a -eq $b ] 返回 false。
-ne检测两个数是否不相等,不相等返回 true。[ $a -ne $b ] 返回 true。
-gt检测左边的数是否大于右边的,如果是,则返回 true。[ $a -gt $b ] 返回 false。
-lt检测左边的数是否小于右边的,如果是,则返回 true。[ $a -lt $b ] 返回 true。
-ge检测左边的数是否大于等于右边的,如果是,则返回 true。[ $a -ge $b ] 返回 false。
-le检测左边的数是否小于等于右边的,如果是,则返回 true。[ $a -le $b ] 返回 true。
运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。

-lt                #表示小于

-gt                  #表示大于

-eq                  #表示等于

-qw              #表示是否

-ne               #表示非、不等于

-ge               #表示 大于等于

-b                  #表示判断是不是

字符串运算符

运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否为0不为0返回 true。[ -n "$a" ] 返回 true。
$检测字符串是否为空不为空返回 true[ $a ] 返回 true。

正则表达式元字符

78863e240b35a34d1aabcb13b717e8ecaf0.jpg

  • 特殊的元字符

2cf224d57db4df1d556a9cc030ffb3fa4bb.jpg

  • 扩展的正则表达式

a446081e56d33d146a7497030751ee90ba8.jpg

 

Linux 教程

Linux 教程Linux 简介Linux 安装Linux 系统启动过程Linux 系统目录结构Linux 忘记密码解决方法Linux 远程登录Linux 文件基本属性Linux 文件与目录管理Linux 用户和用户组管理Linux 磁盘管理Linux vi/vimlinux yum 命令

Shell 教程

Shell 教程Shell 变量Shell 传递参数Shell 数组Shell 运算符Shell echo命令Shell printf命令Shell test 命令Shell 流程控制Shell 函数Shell 输入/输出重定向Shell 文件包含

Linux 参考手册

Linux 命令大全Nginx 安装配置MySQL 安装配置

 Shell echo命令

Shell test 命令 

Shell printf 命令

上一章节我们学习了 Shell 的 echo 命令,本章节我们来学习 Shell 的另一个输出命令 printf。

printf 命令模仿 C 程序库(library)里的 printf() 程序。

printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。

printf 命令的语法:

printf  format-string  [arguments...]

参数说明:

  • format-string: 为格式控制字符串
  • arguments: 为参数列表。

实例如下:

$ echo "Hello, Shell"
Hello, Shell
$ printf "Hello, Shell\n"
Hello, Shell
$

接下来,我来用一个脚本来体现printf的强大功能:

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
 
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

执行脚本,输出结果如下所示:

姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99

%s %c %d %f都是格式替代符

%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

%-4.2f 指格式化为小数,其中.2指保留2位小数。

 

更多实例:

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
 
# format-string为双引号
printf "%d %s\n" 1 "abc"

# 单引号与双引号效果一样 
printf '%d %s\n' 1 "abc" 

# 没有引号也可以输出
printf %s abcdef

# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def

printf "%s\n" abc def

printf "%s %s %s\n" a b c d e f g h i j

# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d \n"

执行脚本,输出结果如下所示:

1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j  
 and 0

printf的转义序列

序列说明
\a警告字符,通常为ASCII的BEL字符
\b后退
\c抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f换页(formfeed)
\n换行
\r回车(Carriage return)
\t水平制表符
\v垂直制表符
\\一个字面上的反斜杠字符
\ddd表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd表示1到3位的八进制值字符

 

 

31、题目要求  :获取网卡ip、 获取网卡ip显示颜色

提示用户输入网卡的 名字,然后我们用脚本输出网卡的ip,需要考虑下面问题:  

  1. 输入的字符不符合网卡名字规范,怎么应对。
  2. 名字符合规范,但是根本就没有这个网卡又怎么应对。
参考答案
#!/bin/bash
ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/eth.list
while :
do
    eths=`cat /tmp/eth.list |xargs`
    read -p "Please input a if name(The eths is `echo -e "\033[31m$eths\033[0m"`): " eth
    if [ -z "$eth" ]
    then
	echo "Please input a if name."
	continue
    fi
    if ! grep -qw "$eth" /tmp/eth.list
    then
	echo "The if name is error."
	continue
    else
	break
    fi
done

if_ip() 
{
    ip add show dev $1 |grep ' inet ' |awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt
    n=`wc -l /tmp/$1.txt|awk '{print $1}'`
    if [ $n -eq 0 ]
    then
	echo "There is no ip address on the eth."
    else
	echo "The ip addreess is:"
        for ip in `cat /tmp/$1.txt`
	do
	    echo -e "\033[33m$ip\033[0m"
	done
    fi
}

if_ip $eth

实例 : 

[root@localhost ~]# # ip add                                 #  查看机器上所有的网卡

bb89fa9bd49de17606ccf469433013146a7.jpg

[root@localhost ~]# # ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}'                #查看所有的网卡列表

f8d412f68081462a9765d79273f431d4e2a.jpg

[root@localhost ~]# # ip add show dev ens33 | grep ' inet ' |awk '{print $2}'                                   #获取ens33网卡的IP,并精准截取IP所在的第二行。/24表示是IP地址的netmask网段

fef1a6b508dc53b381e92bbcf0e06e38edf.jpg

b7bb56754426dbc21c9c3b21490e2f6c552.jpg

输入网卡的名字 ,运行脚本,查看结果,

058bd8ab7a59b46bcf95ad3d25ebe9268cc.jpg

如果输入了。错的网卡名字,会提示网卡名字错误。输入正确的网卡名字,就直接显示IP地址,然后退出。

62701e86f5e573269591ce6007e380821b7.jpg

未添加颜色,执行脚本之后,显示的结果。

1ff5fd803289f3f7c17a910428de5e6a87b.jpg

 

注意  : 

cat /tmp/eth.list |xargs                       #在脚本中表示列出所有的网卡的名字

[root@localhost ~]# echo "Please input a if name(The eths is 'cat /tmp/eth.list|xargs')"                              #查看网卡列表中的eth网卡

f4d5d304a35af66a8538fcae196a8405245.jpg

 

 if [ -z "$eth" ]                #表达的含义,是如果eth是空的,就提示用户 :  Please input a if name.  

 if ! grep -qw "$eth" /tmp/eth.list            #表达的含义,是如果eth是不在/tmp/eth.list 文件中,就提示用户 :  The if name is error.

 

if_ip                          #函数的名字

ip add show dev $1 |grep ' inet ' |awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt                       #显示IP网卡的IP地址,并把输出的结果存入/tmp/$1.txt临时文件中  ,$1表示第一个参数。  

wc -l /tmp/$1.txt|awk '{print $1}                           #先统计/tmp/$1.txt临时文件中的行数。

 

if [ $n -eq 0 ]         #如果eq等于0,那么提示用户 “There is no ip address on the eth.”

 

31.2 获取网卡ip显示颜色

案例

echo显示带颜色,需要使用参数-e

格式如下 : 

echo -e "\033"[字背景颜色;文字颜色m字符串\033[0m

例如 : 

echo -e"\033[41;37m TonyZhang \033[0m"

其中41的位置代表底色,37的位置是代表字的颜色

注 :

1、字背景颜色和文字颜色之间是英文的”""”

2、文字颜色后面有个m

3、字符串前后可以没有空格,如果有的话,输出也是同样有空格

例子 :

echo -e "/033[30m 黑色字 \033[0m"

echo -e "/033[31m 红色字 \033[0m"

echo -e "/033[30m 绿色字 \033[0m"

echo -e "/033[30m 黄色字 \033[0m"

echo -e "/033[30m 蓝色字 \033[0m"

echo -e "/033[30m 紫色字 \033[0m"

echo -e "/033[30m 蓝色字 \033[0m"

echo -e "/033[30m 白色字 \033[0m"

echo -e "/033[30m 黑底白色字 \033[0m"

 

echo -e "/033[30m红底 白字 \033[0m"

echo -e "/033[30m 绿底白字 \033[0m"

echo -e "/033[30m 黄底白字 \033[0m"

echo -e "/033[30m 蓝底白字 \033[0m"

为网卡的名称显示颜色。

#!/bin/bash
ip add |awk -F ': ' '$1 ~ "^[1-9]" {print $2}' > /tmp/eth.list
while :
do
    eths=`cat /tmp/eth.list |xargs`
    read -p "Please input a if name(The eths is '/tmp/eth.list|xargs'): " eth
    if [ -z "$eth" ]
    then
	echo "Please input a if name."
	continue
    fi
    if ! grep -qw "$eth" /tmp/eth.list
    then
	echo "The if name is error."
	continue
    else
	break
    fi
done

if_ip() 
{
    ip add show dev $1 |grep ' inet ' |awk '{print $2}'|awk -F '/' '{print $1}' >/tmp/$1.txt
    n=`wc -l /tmp/$1.txt|awk '{print $1}'`
    if [ $n -eq 0 ]
    then
	echo "There is no ip address on the eth."
    else
	echo "The ip addreess is:"
        `cat /tmp/$1.txt

    fi
}

if_ip $eth

添加颜色,执行脚本之后,显示的结果。

62701e86f5e573269591ce6007e380821b7.jpg

 

32、题目要求  : 列出目录内容

写一个脚本,实现如下功能:  

  1. 脚本可以带参数也可以不带
  2. 参数可以有多个,每个参数必须是一个目录
  3. 脚本检查参数个数,若等于0,则列出当前目录本身,否则显示每个参数包含的子目录。

【核心要点】

$#参数个数

test -d filename                     #

find $d -type d                      #把当前文件下的文件全部列出来

参考答案
#!/bin/bash
if [ $# -eq 0 ]
then
    echo "当前目录下的文件是:"
    ls .
else
    for d in $@
    do
	if [ -d $d ]
	then
	    echo "目录$d下有这些子目录:"
	    find $d -type d 
	else
	    echo "并没有该目录:$d"
	fi
    done
fi

实例 : 

查看当前目录下的文件

2783806d75c74ffe9ea48fdc20852bec243.jpg

c2bde1bd169891b0d1aa361180c5d9016c0.jpg

ba9eca8ef81da9a5d53fa0465a7f330ec34.jpg

显示tmp和/usr/local目录下的文件

6e90fa222c1ee8e0654bfa399117dd694a2.jpg

 

33、题目要求   : 下载文件

定义一个shell函数,能接受两个参数,满足以下要求:  

  1. 第一个参数为URL,即可下载的文件,第二个参数为目录,即下载后保存的位置
  2. 如果用户给的目录不存在,则提示用户是否创建,如果创建就继续执行,否则,函数返回一个51的错误值给调用脚本
  3. 如果给的目录存在,则下载文件,下载命令执行结束后测试文件下载成功与否,如果成功,则返回0给调用脚本,否则,返回52给调用脚本
参考答案
#!/bin/bash
if [ $# -ne 2 ]
then
   echo "你必须要输入两个参数,第一个参数是网址,第二个参数是目录." 
   exit 1
fi

if [ ! -d $2 ]
then
    while :
    do
    echo "你输入的第二个参数,并不是一个存在的目录。是否要创建该目录呢?(y|n): "c
    case $c in 
	y|Y)
	    mkdir -p $2
	    ;;
	n|N)
	    exit 51
	    ;;
	*)
	    echo "请输入y或者n."
	    continue
	    ;;
    esac
    done
else
    cd $2
    wget $1 
    if [ $? -eq 0 ]
    then
	exit 0
    else
	echo "下载失败."
	exit 52
    fi
fi

实例 : 

运行脚本,得到结果是1,说明脚本没问题。返回52给调用脚本,给的目录不存在,则下载文件失败,

14977818609b771827cff7702199eed713a.jpg

脚本解析失败,原因后面没有两个参数,

14957e7efe805d73180a80e3cbd7fed01a0.jpg

输入两个参数,第一个参数是网址,第二个参数是目录时,就解析成功了。

03eaf31c764028304357e0bc5f8333be051.jpg

查看下载的文件

7bc043e33cbfd619ea12acca9cb449d08bd.jpg

 

注意  : 

if [ $# -ne 2 ]                       #如果参数不等于2,提示 : 你必须要输入两个参数,第一个参数是网址,第二个参数是目录.

if [ ! -d $2 ]                            #如果$2是一个不存在的目录,提示 :你输入的第二个参数,并不是一个存在的目录。是否要创建该目录呢?(y|n): 

 

 mkdir -p $2                           #如果客户输入了y或者Y,创建这个目录。如果输入N|n,直接退出。

 

    cd $2
    wget $1                       #表示如果没有,就cd切换到$2,然后wegt下载

 

if [ $? -eq 0 ]                 #如果$?等于0,表示下载成功就退出,否则就是下载失败。

 

报错原因 : 未安装命令。解决办法  : yum install -y wget

d5dcc1721f59748edbf128c7c3af2bfff67.jpg

 

34、题目要求  :  猜数字

写一个shell脚本,能实现如下需求:  

  1. 执行脚本后,提示输入名字(英文的,可以是大小写字母、数字不能有其他特殊符号),然后输出一个随机的0-99之间的数字,脚本并不会退出,继续提示让输入名字
  2. 如果输入相同的名字,输出的数字还是第一次输入该名字时输出的结果
  3. 前面已经输出过的数字,下次不能再出现
  4. 当输入q或者Q时,脚本会退出。
参考答案
#!/bin/bash
n=$[$RANDOM%101]
while :
do
    read -p "请输入一个0-100的数字:" n1
    if [ -z "$n1" ]
    then
	echo "必须要输入一个数字。"
	continue
    fi
    n2=`echo $n1 |sed 's/[0-9]//g'`
    if [ -n "$n2" ]
    then
	echo "你输入的数字并不是正整数."
	continue
    else
	if [ $n -gt $n1 ]
	then
	    echo "你输入的数字小了,请重试。"
	    continue
	elif [ $n -lt $n1 ]
	then
	    echo "你输入的数字大了,请重试。"
	    continue
	else
	    echo "恭喜你,猜对了!"
	    break
	fi
    fi
done

实例 : 

获取一个随机的数字

20446400a524f5f0ae8cd6eee5b69bc4938.jpg

获取一个100以内的随机数字

b66ab0b08c1154d4b820f6fb50f7b6775de.jpg

运行0-99的脚本,输入一个正确的随机数字,就结束了。

4b514d0f6f46ccdccaa9505060e6f5255d0.jpg

 

 

35.1、题目要求   :   根据名字得数字

写一个shell脚本,能实现如下需求:  

  1. 执行脚本后,提示输入名字(英文的,可以是大小写字母、数字不能有其他特殊符号),然后输出一个随机的0-99之间的数字,脚本并不会退出,继续提示让输入名字
  2. 如果输入相同的名字,输出的数字还是第一次输入该名字时输出的结果
  3. 前面已经输出过的数字,下次不能再出现
  4. 当输入q或者Q时,脚本会退出。
参考答案
#!/bin/bash
f=/tmp/user_number.txt
while :
do
    read -p "Please input a username: " u
    u1='echo $u|sed 's/[a-zA-Z0-9]//g''	
    if [ -n "$u1" ]
    then
	echo "你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合"
	continue
    else
	if [ -f $f ]
	then
	    u_n=`awk -v uu=$u '$1==uu {print $2}' $f`
	    if [ -n "$u_n"  ]
	    then
		     echo "用户$u对应的数字是:$u_n"
	    else
		    n=$[$RAMDOM%100]
	        echo "用户$u对应的数字是 : $n"
            echo $u $n >> $f
	    fi
	else
	    n=$[$RAMDOM%100]
	    echo "用户$u对应的数字是:$n"
	    echo $u $n >> $f
	fi
    fi
done

实例 : 

查看运行的结果,/tmp/user_number.txt文件没有创建。

73efff857b983e2887a17a90ec484f18e6a.jpg

当第二次执行脚本时,/tmp/user_number.txt就创建了。输入q或者大写的    Q,退出 运行的脚本。不建议使用ctrl +c.

bfbde1006861c91335244a0c042d15aebc0.jpg

 

注意  : 

u_n                               #u_n的值为1

if [ -n "$u_n" ]                    #如果u_n不为空,那么$u对应的变量就是$u_n ;否则,重新创造一个随机数。

 

`echo $u|sed 's/[a-zA-Z0-9]//g'`                  #如果输入u的值,是空的,说明用户输入的名字是对的

-n "$u1"                 #如果输入的不为空,。提示 “你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合”

"$u $n" >>$f                          #将用户名和对应的数字,记录到/tmp/user_number.txt文件中

 

awk '{print $2}' $f|grep -qw $n                #查找/tmp/user_number.txt文件中第二段截取出来,

u_n=`awk -v uu=$u '$1==uu {print $2}' $f`                      #求用户名中的行数,并截取/tmp/user_number.txt文件中第二段

 

35.2 根据名字得数字优化

参考答案
#!/bin/bash
f=/tmp/user_number.txt
j_n()
{
    while :
    do
	n=$[RANDOM%100]
	if awk '{print $2}' $f|grep -qw $n
	then
	    continue
	else
	    break
	fi
    done
}

while :
do
    read -p "Please input a username: " u
    if [ -z "$u" ]
    then
	echo "请输入用户名."
	continue
    fi

    if [ $u == "q" ] || [ $u == "Q" ]
    then
	exit
    fi 

    u1=`echo $u|sed 's/[a-zA-Z0-9]//g'`
    if [ -n "$u1" ]
    then
	echo "你输入的用户名不符合规范,正确的用户名应该是大小写字母和数字的组合"
	continue
    else
	if [ -f $f ]
	then
	    u_n=`awk -v uu=$u '$1==uu {print $2}' $f`
	    if [ -n "$u_n" ]
	    then
		echo "用户$u对应的数字是:$u_n"
	    else
		j_n
		echo "用户$u对应的数字是:$n"
	        echo "$u $n" >>$f
	    fi
	else
	    j_n
	    echo "用户$u对应的数字是:$n"
	    echo $u $n >> $f
	fi
    fi
done

注意  : 

if awk '{print $2}' $f|grep -qw $n                  #表示查看/tmp/user_number.txt文件第二端,是否已经出现了$n随机数?

 

36、题目要求  :  一个数字的行

系统logrotate工具,可以完成日志切割、归档。写一个shell脚本实现类似的归档功能。   举例: 假如服务的输出日志是1.log,要求每天归档一个,1.log第二天就变成1.log.1,第三天1.log.2, 第四天 1.log.3  一直到1.log.5。

参考答案
#!/bin/bash
cd /data/logs
log=1.log
mv_log()
{
    [ -f $1 ] && mv $1 $2
}
[ -f 1.log.5 ] && rm -f 1.log.5
for i in `seq 4 -1 1`
do 
    j=$[$i+1]
    mv_log $log.$i $log.$j
done
mv 1.log 1.log.1

实例 : 

统计行中出现的数字

b60da2637a1664989c111e5797ed196fc11.jpg

 

注意  : 

echo $line |sed 's/[^0-9]//g' |wc -L                    #统计所有的行,将所有的非数字全部删除,只剩下数字,并计算数字的个数。

 

37、题目要求   :    日志切割归档

系统logrotate工具,可以完成日志切割、归档。写一个shell脚本实现类似的归档功能。   举例: 假如服务的输出日志是1.log,要求每天归档一个,1.log第二天就变成1.log.1,第三天1.log.2, 第四天 1.log.3  一直到1.log.5。

参考答案
#!/bin/bash
cd /data/logs
log=1.log
mv_log()
{
    [ -f $1 ] && mv $1 $2
}
[ -f 1.log.5 ] && rm -f 1.log.5
for i in `seq 4 -1 1`
do 
    j=$[$i+1]
    mv_log $log.$i $log.$j
done
mv 1.log 1.log.1

实例 : 

创建/data/logs目录 , 然后在1.log里面写入111

6a05c734ada94d322576d8ca8cb69331e67.jpg

往2.log日志里面写入222,按照顺序,依次在日志里面写入对应的数字,如:3.log里面写333.

acdb4b0518804a05acb3c41055f719f9c06.jpg

查看脚本是否有问题,在1.log日志文件中写入000.然后执行 “cat *”命令,查看运行结果。应该系统日志只有两个,所以显示的结果到222,就结束了。

2b4af53dade7a2e345e67c163ae156e7a5e.jpg

 

注意  : 

log=1.log                                     #log是定义的变量

mv_log()                                     #定义的函数

[ -f $1 ] && mv $1 $2                            #如果$1存在,就把$1改成$2

[ -f 1.log.5 ] && rm -f 1.log.5                 #如果1.log.5存在,就删除1.log.5

 

38、题目要求   :  查找在线IP

写一个shell脚本,把192.168.0.0/24网段在线的ip列出来。

参考答案
#!/bin/bash
for i in `seq 1 254`
do 
    if ping -c 2 -W 2 192.168.0.$i >/dev/null 2>/dev/null
    then
	echo "192.168.0.$i 是通的."
    else
	echo "192.168.0.$i 不通."
    fi
done

实例 : 

有两个IP地址,测试一个通的,返回ok,一个不通的,什么都不返回。

7049cbf777864664364e76396eea762496d.jpg

执行脚本,查看脚本运行的结果。因为这个网段,不通,所以全部都不通

9c4c3984ca4ffc6ce2e7ea716e5b1d47706.jpg

 

注意  : 

for i in `seq 1 254`                                   #ping的IP地址范围1-254

if ping -c 2 -W 2 192.168.0.$i >/dev/null 2>/dev/null                  #把能ping通的IP地址写入到/dev/nul,错误的也写入/dev/null  。-c 2表示ping两次,-W 2  表示ping的时间为两秒

 

 

39、题目要求   :  检查脚本错误

写一个shell脚本,检查指定的shell脚本是否有语法错误,若有错误,首先显示错误信息,然后提示用户输入q或者Q退出脚本,输入其他内容则直接用vim打开该shell脚本。

参考答案
#!/bin/bash
sh -n $1 2>/tmp/sh.err
if [ $? -ne 0 ]
then
    cat /tmp/sh.err
    read -p "请输入q/Q退出脚本。" c
    if [ -z "$c"]
    then
	vim $1
        exit 0
    fi
    if [ $c == q ] || [ $c == Q ]
    then
	exit 0
    else
	vim $1
	exit 0
    fi
else
    echo "脚本$1没有语法错误."
fi

实例 : 

脚本运行结果。

57e6ec0988e34f8e02ed26c9ed6223eeb72.jpg

注意  : 

sh -n $1 2>/tmp/sh.err                    #将错误的输出到/tmp/sh.err  

if [ $? -ne 0 ]                              #$?不等于0,说明有语法错误。

 

40、题目要求   :  格式化数字

输入一串随机数字,然后按千分位输出。   比如输入数字串为“123456789”,输出为123,456,789。

参考答案
#!/bin/bash
n=`echo $1|wc -L`
for d in `echo $1|sed 's/./& /g'`
do
    n2=$[$n%3]
    if [ $n2 -eq 0 ]
    then
	echo -n ",$d"
    else
	echo -n "$d"
    fi
    n=$[$n-1]
done |sed 's/^,//'
echo

实例 : 

sed实现数字之间的自动空一格

ca49b61776752b8c0f43659bf4ec5aab6cd.jpg

脚本正确执行的结果

05f700f32976b763f5be0827d79b00e9431.jpg

 

注意  : 

n=`echo $1|wc -L`                       #n表示计算数字的长度,$1是数字串。

for d in `echo $1|sed 's/./& /g'`                          #sed实现数字的自动空一格,&代表前面的点。

    n2=$[$n%3]                                    #$[$n%3] 表示$n除以3,然后添加逗号间隔。
    if [ $n2 -eq 0 ]                                 #0表示$n2能够被3整除

 

    echo -n ",$d"                            #能被3整除的,添加逗号间隔。

  echo -n "$d"                           #不能被3整除的,不添加逗号间隔。

 

来源 :https://github.com/aminglinux/shell100/blob/master/13.md

转载于:https://my.oschina.net/u/3803405/blog/3001142

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Shell脚本高级编程教程,希望对你有所帮助。 Example 10-23. Using continue N in an actual task: 1 # Albert Reiner gives an example of how to use "continue N": 2 # --------------------------------------------------------- 3 4 # Suppose I have a large number of jobs that need to be run, with 5 #+ any data that is to be treated in files of a given name pattern in a 6 #+ directory. There are several machines that access this directory, and 7 #+ I want to distribute the work over these different boxen. Then I 8 #+ usually nohup something like the following on every box: 9 10 while true 11 do 12 for n in .iso.* 13 do 14 [ "$n" = ".iso.opts" ] && continue 15 beta=${n#.iso.} 16 [ -r .Iso.$beta ] && continue 17 [ -r .lock.$beta ] && sleep 10 && continue 18 lockfile -r0 .lock.$beta || continue 19 echo -n "$beta: " `date` 20 run-isotherm $beta 21 date 22 ls -alF .Iso.$beta 23 [ -r .Iso.$beta ] && rm -f .lock.$beta 24 continue 2 25 done 26 break 27 done 28 29 # The details, in particular the sleep N, are particular to my 30 #+ application, but the general pattern is: 31 32 while true 33 do 34 for job in {pattern} 35 do 36 {job already done or running} && continue 37 {mark job as running, do job, mark job as done} 38 continue 2 39 done 40 break # Or something like `sleep 600' to avoid termination. 41 done 42 43 # This way the script will stop only when there are no more jobs to do 44 #+ (including jobs that were added during runtime). Through the use 45 #+ of appropriate lockfiles it can be run on several machines 46 #+ concurrently without duplication of calculations [which run a couple 47 #+ of hours in my case, so I really want to avoid this]. Also, as search 48 #+ always starts again from the beginning, one can encode priorities in 49 #+ the file names. Of course, one could also do this without `continue 2', 50 #+ but then one would have to actually check whether or not some job 51 #+ was done (so that we should immediately look for the next job) or not 52 #+ (in which case we terminate or sleep for a long time before checking 53 #+ for a new job).

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值