linux shell编程-bash的奇技淫巧
本文主要讲bash脚本中容易出错和很少用但是用起来有意想不到效果的部分。
循环:
正常的for循环:
for i in a b c 1 2 3; do
echo "$i"
done
数字序列循环:
for i in `seq `; do
echo "$i"
done
其中的 `seq ` 也可以换成 {..}
{开始..结尾}的这种形式可以表示连续的数列,可以从小到大也可以从大到小,但是可惜不像python的range()那样可以指定间隔量
C语言风格的for循环:
for (( i=; i<; i++ )); do
echo "$i"
done
for循环迭代文本
for循环会使用空格、换行符、制表符分割文本,依次迭代,如:
a="ab cd
ef" for i in $a; do
echo "$i"
done
输出结果:
ab
cd
ef
shell分割文本其实是以一个全局变量$IFS为依据的,默认情况下IFS=$'\n\t '(即换行符、制表符、空格),可以通过修改IFS的值来改变迭代文本的分割方式。
请注意上面的$a如果加引号括起来的话,会把它当成一个整体,不会切割迭代。
数学计算
双括号“(())”还可以用于数学计算:
(( a=+ ))
echo $a
#
在双括号中,变量并不需要用$符号来引用,英文单词天然是变量。
变量:
间接引用:
a=b
b=
echo ${!a}
#
效果等同于 eval echo \$$a
特殊字符转义
包含特殊字符的字符串:
echo "ab\ncd"
上列命令会输出字符ab+换行+cd,但是实际上字符串"ab\ncd"中并不包含“换行”这个字符,输出的换行只是echo命令解析的结果。
# a="ab\ncd"
# echo "length of var a is ${#a}" length of var a is
通过${#var}的形式可以得到一个字符串的长度,上面示例可以看出来,字符串"ab\ncd"的长度是6而不是预期的5。
那么能否将不可打印的字符赋值给变量呢?答案是肯定的:
# a=$'\x61\n\x62'
# echo "$a"
a
b
请注意一定用的是单引号“'”,用双引号括起来是不起转义作用的。
字符串操作
变量值字符截取:
a="abcdefg"
echo ${a:}
# cdefg
echo ${a::}
# 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
#
echo ${a:-} # 如果没定义或是空值,则表达式采用默认值789
#
echo ${b-} # 如果没定义,则表达式采用默认值789,b定义了
#
echo ${b:-} # 如果没定义或是空值,则表达式采用默认值789
#
echo $a # 原变量并没有被赋值
#
echo $b # 原变量并没有被赋值
#
b=
echo ${b-} # 如果变量已经被赋值,则不改变原有值
#
unset a
echo ${a=} # 如果a没定义,则表达式采用默认值,并给a赋值
#
echo $a
# # a已经被赋值了
a=""
echo ${a=}
#
echo ${a:=} # 加冒号:的作用和之前一样
#
echo $a
#
前面讲了用“-”和“=”的,还有一种用“+”的,用于当变量已经被赋值的情况下采用默认值,举一反三,不赘述了。
位置变量
$0是文件名,$#代表参数个数,$1,$2等等表示执行该脚本或函数后面跟的位置参数,$1代表第一个参数,依次类推,需要注意的是,第9个以后的参数应该这么表示:
${}
这表示第10个参数,必须用花括号括起来,否则就变成第1个变量后面加个字符“0”了。因为这个有的人以为第9个以后的位置变量就不可用了,是错的。
$@和$*都表示所有的变量,但是区别是前者将每个作为一个字符串,是多个字符串的结合,而后者将所有变量组合成一个字符串,用空格分隔。
这样不同会在for循环里面造成使用的区别,在for循环里面,如果加上引号 for i in "$@" 和 for i in "$*" 是不同的,前者还是会依次把参数代入循环,而后者会吧所有参数作为字符串一次性代入:
echo '
for i in "$@"; do
echo "$i"
done
for i in "$*"; do
echo "$i"
done
' > myscript.sh
chmod myscript.sh
./myscript.sh abc def
结果是:
abc def
abc def
那么$@加引号和不加引号有区别么?
大部分情况下结果看起来是一样的,但会在某些情况下造成麻烦,因为for循环会用换行符“\n”和空格来拆分变量,所以如果调用脚本所带的参数中带有空格或者换行符,不加引号的时候会把这个参数拆开了依次代入,而加了引号就可以避免这种情况。
echo '
for i in "$@"; do
echo "$i"
done
for i in $@ ; do
echo "$i"
done
' > myscript.sh
chmod myscript.sh
./myscript.sh abc "123 def"
结果是:
abc
def
abc def
for循环使用数组
将数组的值依次代入循环,可以用${arr[@}和${arr[*]}这两种方法,区别和加引号的区别同上面位置参数的使用相同。
字符串比较
shell的字符串匹配通常是这样的:
[ "abc" = "abc" ]
echo $?
#
$? 这个变量代表上条命令的返回码。若字符串相同则返回0,否则返回1。除了全匹配外,通过双方括号“[[]]”还可以用正则表达式匹配
[[ "abc234def" =~ ^abc[-]{}[a-z]+$ ]]
echo $?
#
注意这里正则表达式不能用引号括起来,而且只支持基本的正则,不支持如“\b \S”之类的扩展。
另单方括号‘[ ]’和双方括号‘[[ ]]’的区别,单括号等同于bash内置test命令,双方括号不是命令,是bash关键字。
原文地址:http://www.cnblogs.com/foxgab/p/6901782.html
如果觉得本文对您有帮助,请扫描后面的二维码给予捐赠,您的支持是作者继续写出更好文章的动力!
linux shell编程-bash的奇技淫巧的更多相关文章
- linux —— shell 编程(文本处理)
导读 本文为博文linux —— shell 编程(整体框架与基础笔记)的第4小点的拓展.(本文所有语句的测试均在 Ubuntu 16.04 LTS 上进行) 目录 基本文本处理 流编辑器sed aw ...
- linux —— shell 编程(编程语法)
导读 本文为博文linux —— shell 编程(整体框架与基础笔记)的第4小点的拓展.(本文所有语句的测试均在 Ubuntu 16.04 LTS 上进行) 目录 再识变量 函数 条件语句 循环语句 ...
- linux shell编程总结
linux shell编程总结 本周学习了unix/linux shell编程,参考的是<LINUX与UNIX Shell 编程指南>,David Tansley著:徐焱,张春萌等译,由机 ...
- Linux Shell编程参考大全
本文记录Linux Shell编程中常用基本知识,方便快速入门以及查询使用. 本文主要分为以下几个部分: 一.Shell中的变量 任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识. ...
- linux shell 编程参考
#!/bin/bash my_fun() { echo "$#" } echo 'the number of parameter in "$@" is '$(m ...
- 一文学完Linux Shell编程,比书都好懂
一. Shell 编程 1. 简介 Shell 是一个用 C 语言编写的程序,通过 Shell 用户可以访问操作系统内核服务. Shell 既是一种命令语言,又是一种程序设计语言. Shell scr ...
- 前端学习 linux —— shell 编程
前端学习 linux - shell 编程 shell 原意是"外壳",与 kernel(内核)相对应,比喻内核外的一层,是用户和内核沟通的桥梁.shell 有很多种,国内通常使用 ...
- Linux Shell编程中的几个特殊符号命令 & 、&& 、 ||
https://blog.csdn.net/hack8/article/details/39672145 Linux Shell编程中的几个特殊符号命令 & .&& . || ...
- Linux Shell编程与编辑器使用详解
<Linux Shell编程与编辑器使用详解> 基本信息 作者: 刘丽霞 杨宇 出版社:电子工业出版社 ISBN:9787121207174 上架时间:2013-7-22 出版日期:201 ...
随机推荐
- C#网络程序设计(2)Socket基础编程
本节介绍如何使用基础Socket实现TCP通信. (1)Socket详细介绍: Socket的英文原义是"孔"或"插座".通常称作"套 ...
- 【解决问题】解决python安装模块时UnicodeDecodeError
安装模块时,出现报错: UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 68: ordinal not in ...
- web前端技术框架选型参考
一.出发点 随着Web技术的不断发展,前端架构框架.UI框架.构建工具.CSS预处理等层出不穷,各有千秋.太多的框架在形成初期,都曾在web领域 掀起过一场技术浪潮,可有些却仅仅是昙花一现,随着他们用 ...
- 程序员要拥抱变化,聊聊Android即将支持的Java 8
WeTest 导读 Java 9预计今年也会正式发布,Java 8这个最具变革性且变革性最适于GUI程序的版本,Android终于准备正式支持.从自己开发JavaFx的感受,说一说Java 8应该使用 ...
- Android开发之旅:环境搭建及HelloWorld(转)
本系列适合0基础的人员,因为我就是从0开始的,此系列记录我步入Android开发的一些经验分享,望与君共勉!作为Android队伍中的一个新人的我,如果有什么不对的地方,还望不吝赐教. 在开始Andr ...
- Linux下Hadoop2.7.1集群环境的搭建(超详细版)
本文旨在提供最基本的,可以用于在生产环境进行Hadoop.HDFS分布式环境的搭建,对自己是个总结和整理,也能方便新人学习使用. 一.基础环境 ...
- 手把手教你学SVN
注意 转载须保留原文链接(http://www.cnblogs.com/wzhiq896/p/6822713.html ) 作者:wangwen896 整理 对于很多新手来说,SVN 代码托管一无所 ...
- HDU4712 Hamming Distance (随机化)
link:http://acm.hdu.edu.cn/showproblem.php?pid=4712 题意:给1e5个数字,输出这些数中,最小的海明码距离. 思路:距离的范围是0到20.而且每个数的 ...
- linux c++爬虫(一)
int main(int argc, void *argv[]) { ]; ; char ch; ) { switch(ch) { case 'v': version(); break; case ' ...
- Day1-用户输入及字符串格式化输入
1.用户输入--input和getpass函数 2.字符串的格式化 ############################################# 一.用户输入--input()函数 #! ...