linux shell编程-bash的奇技淫巧

Posted foxgab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux shell编程-bash的奇技淫巧相关的知识,希望对你有一定的参考价值。

本文主要讲bash脚本中容易出错和很少用但是用起来有意想不到效果的部分。

循环:

正常的for循环:

for i in a b c 1 2 3; do
    echo "$i"
done

数字序列循环:

for i in `seq 100`; do
    echo "$i"
done

其中的 `seq 100` 也可以换成 {1..100} 

{开始..结尾}的这种形式可以表示连续的数列,可以从小到大也可以从大到小,但是可惜不像python的range()那样可以指定间隔量

C语言风格的for循环:

for (( i=1; i<100; i++ )); do
    echo "$i"
done

数学计算

双括号“(())”还可以用于数学计算:

(( a=123+456 ))
echo $a
# 579

在双括号中,变量并不需要用$符号来引用,英文单词天然是变量。

变量:

间接引用:

a=b
b=100
echo ${!a}
# 100

效果等同于 eval echo \$$a 

字符串操作

变量值的字符长度:

a="abcdefg"
echo ${#a}
# 7

变量值字符截取:

a="abcdefg"
echo ${a:2}
# cdefg
echo ${a:2:3}
# cde

变量值字符删除:(#为从头部开始匹配,%为从尾部匹配,支持通配符“?*”)

a="abdcdefgh"
echo ${a#*d} # 删除字符串头部匹配“*d”的部分,通配符*代表匹配任意多个字符,一个#号代表通配符“*”保守匹配
# cdefgh
echo ${a##*d} # 两个#号表示贪婪匹配
# efgh
echo ${a%d*} # 同上,两个%时代表贪婪匹配
# abdc
a=b
b="abcdefg"
echo "${!a#abc}"
# defg

可以同时支持间接引用和字符删除

变量赋值安全

用于赋值前检查是否已经定义或赋值。

unset a
unset b
b=""    # a没有定义,b定义了但是空值
echo ${a-789}  # 如果没定义,则表达式采用默认值789
# 789
echo ${a:-789}    # 如果没定义或是空值,则表达式采用默认值789
# 789
echo ${b-789}     # 如果没定义,则表达式采用默认值789,b定义了
# 
echo ${b:-789}    # 如果没定义或是空值,则表达式采用默认值789
# 789
echo $a        # 原变量并没有被赋值
#
echo $b        # 原变量并没有被赋值
#
b=123
echo ${b-789}  # 如果变量已经被赋值,则不改变原有值
# 123
unset a
echo ${a=789}    # 如果a没定义,则表达式采用默认值,并给a赋值
# 789
echo $a
# 789        # a已经被赋值了
a=""
echo ${a=789}
#
echo ${a:=789}    # 加冒号:的作用和之前一样
# 789
echo $a
# 789

前面讲了用“-”和“=”的,还有一种用“+”的,用于当变量已经被赋值的情况下采用默认值,举一反三,不赘述了。

位置变量

$0是文件名,$#代表参数个数,$1,$2等等表示执行该脚本或函数后面跟的位置参数,$1代表第一个参数,依次类推,需要注意的是,第9个以后的参数应该这么表示:

${10}

这表示第10个参数,必须用花括号括起来,否则就变成第1个变量后面加个字符“0”了。因为这个有的人以为第9个以后的位置变量就不可用了,是错的。

[email protected]和$*都表示所有的变量,但是区别是前者将每个作为一个字符串,是多个字符串的结合,而后者将所有变量组合成一个字符串,用空格分隔。

这样不同会在for循环里面造成使用的区别,在for循环里面,如果加上引号 for i in "[email protected]" 和 for i in "$*" 是不同的,前者还是会依次把参数代入循环,而后者会吧所有参数作为字符串一次性代入:

echo for i in "[email protected]"; do
    echo "$i"
done
for i in "$*"; do
    echo "$i"
done
 > myscript.sh
chmod 755 myscript.sh
./myscript.sh abc 123 def

结果是:

abc
123
def
abc 123 def

那么[email protected]加引号和不加引号有区别么?

大部分情况下结果看起来是一样的,但会在某些情况下造成麻烦,因为for循环会用换行符“\n”和空格来拆分变量,所以如果调用脚本所带的参数中带有空格或者换行符,不加引号的时候会把这个参数拆开了依次代入,而加了引号就可以避免这种情况。

echo for i in "[email protected]"; do
    echo "$i"
done
for i in [email protected] ; do
    echo "$i"
done
 > myscript.sh
chmod 755 myscript.sh
./myscript.sh abc "123 def"

结果是:

abc
123 def
abc
123
def

for循环使用数组

将数组的值依次代入循环,可以用${arr[@}和${arr[*]}这两种方法,区别和加引号的区别同上面位置参数的使用相同。

字符串匹配

shell的字符串匹配通常是这样的:

[ "abc" = "abc" ]
echo $?
# 0

若字符串相同则返回0,否则返回1。除了全匹配外,通过双方括号“[[]]”还可以用正则表达式匹配

[[ "abc234def" =~ ^abc[0-9]{3}[a-z]+$ ]]
echo $?
# 0

注意这里正则表达式不能用引号括起来,而且只支持基本的正则,不支持如“\b \S”之类的扩展。

 

原文地址:http://www.cnblogs.com/foxgab/p/6901782.html

如果觉得本文对您有帮助,请扫描后面的二维码给予捐赠,您的支持是作者继续写出更好文章的动力!

技术分享


以上是关于linux shell编程-bash的奇技淫巧的主要内容,如果未能解决你的问题,请参考以下文章

linux虚拟机下bash shell编程,制作一个音乐播放器,可以实现用代码打开mp3文件吗?

linux学习19 shell脚本基础-bash脚本编程基础及配置文件

linux的shell编程中#!/bin/sh和$bash是啥意思?

linux的shell编程中#!/bin/sh和bash是啥意思?

Linux之shell编程的基本使用

linux shell编程bash编程shell教程bash教程shell文档bash文档shell脚本bash脚本教程第一部分:绪论