[内容] 正则表达式 (转载)

shell正则表达式应用

正则表达式
一、 什么是正则表达式

  什么是正则表达式?正则表达式是用于描述字符排列和匹配模式的一种语法规则。在很多程序设计语言中都支持利用正则表达式来进行字符串的操作,不同语言中的正则表达式略有不同,但是毕竟都是正则,其本质思想都是一致的,当我们掌握了shell中的正则后,再去看python或者perl里面的正则表达式时,会发现其实都是一样的东东。

  在shell的一些命令中,有些并不支持正则表达式,但是它们支持Linux里面的通配符,那么通配符又是什么东东呢,它跟正则表达式又有什么关系?

  正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed等命令都支持正则表达式。通配符用来匹配符合条件的文件名,通配符是完全匹配。ls、find、cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。

Shell通配符主要是下面三个:

*  匹配任意字符

?  匹配任意一个字符 

     []  匹配匹配中括号中的一个字符

                                                                         

首先,正则表达式是用来匹配文件中文本的字符串,而通配符是用来匹配符合条件的文件名;其次正则表达式是包含匹配,只要包含正则中的字符串,就匹配,而通配符是完全匹配,也就是说,必须要与条件中的字符串一模一样才会匹配。 

说了这么多,其实正则表达式主要用于字符串的模式分割、匹配、查找及替换操作,下面来关注一下正则表达式基本的元字符和它的作用。 
二、正则表达式基本的元字符

元字符
	

作用
	

举例说明

*
	

前一个字符匹配0次或者任意多次
	

"a*" 匹配所有内容,包括空白行 
"aa*" 匹配至少包含一个a的行
"aaa*" 匹配最后包含两个连续a的字符串
"aaaaa*"匹配最少包含4个连续a的字符串

.
	

匹配除了换行符外的任意一个字符
	

"s..d" 匹配在s和d这两个字母之间一定有两个

字符的单词
"s.*d" 匹配在s和d字母之间有任意字符
".*" 匹配所有内容

^
	

匹配行首
	

"^hello" 匹配以hello开头的行
"^M" 匹配以大写“M”开头的行

$
	

匹配行尾
	

"hello$" 匹配以hello结尾的行 
"n$" 匹配以小写“n”结尾的行
"^$" 匹配空白行

 

[]
	

匹配中括号中指定的任意一个字符,只匹配一
个字符
	

"[aeiou]" 匹配任意一个元音字母,
"[0-9]" 匹配任意一位数字,
"[a-z][0-9]" 匹配小写字母和一位数字构成的两位字符。
"s[ao]id" 匹配s和i字母中,要么是a,要么是o

"[0-9]"  匹配任意一个数字

"^[a-z]" 匹配小写字母开头的行

[^]
	

匹配中括号的字符以外的任意一个字符
	

"[^0-9]" 匹配任意一位非数字字符,
"[^a-z]" 表示任意一位非小写字母
"^[^a-z]"  匹配不是小写字母开头的行
"^[^a-zA-Z]" 匹配不是字母开头的行

\
	

转义符。用于将特殊符号的含义取消
	

"\.$" 匹配使用"."结尾的行

\{n\}
	

表示其前面的字符恰好出现n次
	

"[0-9]\{4\}" 匹配4位数字,
"[1][3-8][0-9]\{9\}" 匹配手机号码
"a\{3\}"  匹配a字母连续出现3次的字符串
"[0-9]\{3\}" 匹配包含连续的3个数字的字符串

\{n,\}
	

表示其前面的字符出现不小于n次
	

"[0-9]\{2,\}" 表示两位及以上的数字。
"[0-9]\{3,\}[a-z]" 匹配最少用连续3个数字开头

的字符串

\{n,m\}
	

表示其前面的字符至少出现n次,最多出现
m次
	

"[a-z]\{6,8\}" 匹配6到8位的小写字母。
"sa\{1,3\}i" 匹配在字母s和i直接有最少一个a,

最多三个a

( )
	

 
	

 

{ }
	

指定字符出现的次数
	

 

?
	

匹配一个字符0或1次,等价于 {0,1}
	

 

+
	

匹配一个字符1或多次,等价于{1,}
	

 

|
	

 
	

 
三、shell常用正则表达式

 “^\d+$” //非负整数(正整数 + 0)  
“^[0-9]*[1-9][0-9]*$” //正整数  
“^((-\d+)|(0+))$” //非正整数(负整数 + 0)  
“^-[0-9]*[1-9][0-9]*$” //负整数  
“^-?\d+$” //整数  
“^\d+(\.\d+)?$” //非负浮点数(正浮点数 + 0)  
“^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$” //正浮点数  
“^((-\d+(\.\d+)?)|(0+(\.0+)?))$” //非正浮点数(负浮点数 + 0)  
“^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$” //负浮点数  
“^(-?\d+)(\.\d+)?$” //浮点数  
“^[A-Za-z]+$” //由26个英文字母组成的字符串  
“^[A-Z]+$” //由26个英文字母的大写组成的字符串  
“^[a-z]+$” //由26个英文字母的小写组成的字符串  
“^[A-Za-z0-9]+$” //由数字和26个英文字母组成的字符串  
“^\w+$” //由数字、26个英文字母或者下划线组成的字符串  
“^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$” //email地址  
“^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$” //url  
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/   //  年-月-日  
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/   // 月/日/年  
“^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$”   //Emil  
/^((\+?[0-9]{2,4}\-[0-9]{3,4}\-)|([0-9]{3,4}\-))?([0-9]{7,8})(\-[0-9]+)?$/     //电话号码  
“^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$”   //IP地址  

匹配中文字符的正则表达式: [\u4e00-\u9fa5]  
匹配双字节字符(包括汉字在内):[^\x00-\xff]  
匹配空行的正则表达式:\n[\s| ]*\r  
匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/  
匹配首尾空格的正则表达式:(^\s*)|(\s*$)  
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*  
匹配网址URL的正则表达式:^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$  
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$  
匹配国内电话号码:(\d{3}-|\d{4}-)?(\d{8}|\d{7})?  
匹配腾讯QQ号:^[1-9]*[1-9][0-9]*$  
四、元字符及其在正则表达式上下文中的行为 

\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。 
 
 
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。 
 
 
$ 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。 
 
 
* 匹配前面的子表达式零次或多次。 
 
 
+ 匹配前面的子表达式一次或多次。+ 等价于 {1,}。 
 
 
? 匹配前面的子表达式零次或一次。? 等价于 {0,1}。 
 
 
{n} n 是一个非负整数,匹配确定的n 次。 
 
 
{n,} n 是一个非负整数,至少匹配n 次。 
 
 
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。 
 
 
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。 
 
 
. 匹配除 “\n” 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。  
(pattern) 匹配pattern 并获取这一匹配。 
 
 
(?:pattern) 匹配pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。 
 
 
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。 
 
 
(?!pattern) 负向预查,与(?=pattern)作用相反 
 
 
x|y 匹配 x 或 y。 
 
 
[xyz] 字符集合。 
 
 
[^xyz] 负值字符集合。 
 
 
[a-z] 字符范围,匹配指定范围内的任意字符。 
 
 
[^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符。 
 
 
\b 匹配一个单词边界,也就是指单词和空格间的位置。 
 
 
\B 匹配非单词边界。 
 
 
\cx 匹配由x指明的控制字符。 
 
 
\d 匹配一个数字字符。等价于 [0-9]。 
 
 
\D 匹配一个非数字字符。等价于 [^0-9]。 
 
 
\f 匹配一个换页符。等价于 \x0c 和 \cL。 
 
 
\n 匹配一个换行符。等价于 \x0a 和 \cJ。 
 
 
\r 匹配一个回车符。等价于 \x0d 和 \cM。 
 
 
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 
 
 
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 
 
 
\t 匹配一个制表符。等价于 \x09 和 \cI。 
 
 
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 
 
 
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 
 
 
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 
 
 
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。 
 
 
\num 匹配 num,其中num是一个正整数。对所获取的匹配的引用。 
 
 
\n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 
 
 
\nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 
 
 
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 
 
 
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的Unicode字符。 
 
 

匹配中文字符的正则表达式: [u4e00-u9fa5] 
 
 
匹配双字节字符(包括汉字在内):[^x00-xff] 
 
 
匹配空行的正则表达式:n[s| ]*r 
 
 
匹配HTML标记的正则表达式:/<(.*)>.*</1>|<(.*) />/ 
 
 
匹配首尾空格的正则表达式:(^s*)|(s*$) 
 
 
匹配Email地址的正则表达式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)* 
 
 
匹配网址URL的正则表达式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)? 
 
 

利用正则表达式限制网页表单里的文本框输入内容: 

 用正则表达式限制只能输入中文:οnkeyup=”value=value.replace(/[^u4E00-u9FA5]/g,”)” onbeforepaste=”clipboardData.setData('text',clipboardData.getData('text').replace(/[^u4E00-u9FA5]/g,”))” 
 
 
用正则表达式限制只能输入全角字符: οnkeyup=”value=value.replace(/[^uFF00-uFFFF]/g,”)” onbeforepaste=”clipboardData.setData('text',clipboardData.getData('text').replace(/[^uFF00-uFFFF]/g,”))” 
 
 
用正则表达式限制只能输入数字:οnkeyup=”value=value.replace(/[^d]/g,”) “onbeforepaste=”clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,”))” 
 
 
用正则表达式限制只能输入数字和英文:οnkeyup=”value=value.replace(/[W]/g,”) “onbeforepaste=”clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,”))” 
  
五、其他常用正则表达式 

 
 
匹配中文字符的正则表达式: [\u4e00-\u9fa5] 
 
 
匹配双字节字符(包括汉字在内):[^\x00-\xff] 
 
 
匹配空行的正则表达式:\n[\s| ]*\r 
 
 
匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/ 
 
 
匹配首尾空格的正则表达式:(^\s*)|(\s*$) 
 
 
匹配IP地址的正则表达式:/(\d+)\.(\d+)\.(\d+)\.(\d+)/g // 
 
 
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 
 
 
匹配网址URL的正则表达式:http://(/[\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)? 
 
 

sql语句:^(select|drop|delete|create|update|insert).*$ 

 
 
1、非负整数:^\d+$ 
 
 
2、正整数:^[0-9]*[1-9][0-9]*$ 
 
 
3、非正整数:^((-\d+)|(0+))$ 
 
 
4、负整数:^-[0-9]*[1-9][0-9]*$ 
 
 
5、整数:^-?\d+$ 
 
 
6、非负浮点数:^\d+(\.\d+)?$ 
 
 
7、正浮点数:^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)| ([0-9]*[1-9][0-9]*))$ 
 
 
8、非正浮点数:^((-\d+\.\d+)?)|(0+(\.0+)?))$ 
 
 
9、负浮点数:^(-((正浮点数正则式)))$ 
 
 
10、英文字符串:^[A-Za-z]+$ 
 
 
11、英文大写串:^[A-Z]+$ 
 
 
12、英文小写串:^[a-z]+$ 
 
 
13、英文字符数字串:^[A-Za-z0-9]+$ 
 
 
14、英数字加下划线串:^\w+$ 
 
 
15、E-mail地址:^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$ 
 
 
16、URL:^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$  
或:^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^& lt;>\"\"])*$ 
 
 
17、邮政编码:^[1-9]\d{5}$ 
 
 
18、中文:^[\u0391-\uFFE5]+$ 
 
 
19、电话号码:^((\d2,3
)|(\d{3}\-))?(0\d2,3|0\d{2,3}-)?[1-9] \d{6,7}(\-\d{1,4})?$ 
 
 
20、手机号码:^((\d2,3)|(\d{3}\-))?13\d{9}$ 
 
 
21、双字节字符(包括汉字在内):^\x00-\xff 
 
22、匹配首尾空格:(^\s*)|(\s*$)(像vbscript那样的trim函数) 
 
23、匹配HTML标记:<(.*)>.*<\/\1>|<(.*) \/> 
 
24、匹配空行:\n[\s| ]*\r 
 
25、提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *('|”)?(\w|\\|\/|\.)+('|”| *|>)? 
 
26、提取信息中的邮件地址:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 
 
27、提取信息中的图片链接:(s|S)(r|R)(c|C) *= *('|”)?(\w|\\|\/|\.)+('|”| *|>)? 
 
28、提取信息中的IP地址:(\d+)\.(\d+)\.(\d+)\.(\d+) 
 
29、提取信息中的中国手机号码:(86)*0*13\d{9} 
 
30、提取信息中的中国固定电话号码:(\d3,4|\d{3,4}-|\s)?\d{8} 
 
31、提取信息中的中国电话号码(包括移动和固定电话):(\d3,4|\d{3,4}-|\s)?\d{7,14} 
 
32、提取信息中的中国邮政编码:[1-9]{1}(\d+){5} 
 
33、提取信息中的浮点数(即小数):(-?\d*)\.?\d+ 
 
34、提取信息中的任何数字 :(-?\d*)(\.\d+)? 
 
35、IP:(\d+)\.(\d+)\.(\d+)\.(\d+) 
 
36、电话区号:/^0\d{2,3}$/ 
 
37、腾讯QQ号:^[1-9]*[1-9][0-9]*$ 
 
38、帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 
 
39、中文、英文、数字及下划线:^[\u4e00-\u9fa5_a-zA-Z0-9]+$
————————————————
版权声明:本文为CSDN博主「WingoPower」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38382148/java/article/details/78644011

注明:所有转载内容皆直接从被转载文章网页的标题和内容的文本中复制而来

CC 4.0 BY-SA 版权协议网址:https://creativecommons.org/licenses/by-sa/4.0/deed.z

站住补充:

/h 或者 [[:space:]] 匹配空格
/H 或者 [^[:space:]] 不匹配空格

?= 查找某个字符串前面的内容

?<= 查找某个字符串后面的内容

?<! 匹配前面不是某个内容的字符串

?! 匹配后面不是某个内容的字符串

[内容] Linux if 条件判断 (转载)

shell-if表达式(-f,-d,-s,-r,-w,-x,-eq,-ne,-ge,-gt,-le,-lt )

文件表达式

if [ -f file ] 如果文件存在
if [ -d … ] 如果目录存在
if [ -s file ] 如果文件存在且非空
if [ -r file ] 如果文件存在且可读
if [ -w file ] 如果文件存在且可写
if [ -x file ] 如果文件存在且可执行
整数变量表达式

if [ int1 -eq int2 ] 如果int1等于int2
if [ int1 -ne int2 ] 如果不等于
if [ int1 -ge int2 ] 如果>=
if [ int1 -gt int2 ] 如果>
if [ int1 -le int2 ] 如果<=
if [ int1 -lt int2 ] 如果<
字符串变量表达式

If [ $a = $b ] 如果string1等于string2
字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空
if [ $sting ] 如果string 非空,返回0 (和-n类似)
s​h​e​l​l​中​条​件​判​断​i​f​中​的​-​z​到​-​d​的​意​思

[ -a FILE ] 如果 FILE 存在则为真。
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。

[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。

[ -d FILE ] 如果 FILE 存在且是一个目录则为真。

[ -e FILE ] 如果 FILE 存在则为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。

[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -h FILE ] 如果 FILE 存在且是一个符号连接则为真。

[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。 [

-p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。

[ -r FILE ] 如果 FILE 存在且是可读的则为真。

[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。

[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。

[ -w FILE ] 如果 FILE 如果 FILE 存在且是可写的则为真。

[ -x FILE ] 如果 FILE 存在且是可执行的则为真。

[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。

[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。 [ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2,or 如果 FILE1 exists and FILE2 does not则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。

[ -o OPTIONNAME ] 如果 shell选项 “OPTIONNAME” 开启则为真。

[ -z STRING ] “STRING” 的长度为零则为真。
————————————————
版权声明:本文为CSDN博主「打卤」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liyyzz33/java/article/details/84836255

注明:所有转载内容皆直接从被转载文章网页的标题和内容的文本中复制而来

CC 4.0 BY-SA 版权协议网址:https://creativecommons.org/licenses/by-sa/4.0/deed.z
站主补充:
补充一:Shell if 单判断的格式
if [ <judgment condition> ];then
<step to perform>
fi

补充二:Shell if 双判断的格式
if [ <judgment condition> ];then
<step to perform>
else
<step to perform>
fi

补充三:Shell if 多判断的格式
if [ <judgment condition> ];then
<step to perform>
elif
<step to perform>
else
<step to perform>
fi

补充四:Shell if 多条件判断的格式
4.1 与条件的判断
if [ <judgment condition> -a <judgment condition> ];then
<step to perform>
fi

或者:

if [ <judgment condition> ] && [ <judgment condition> ];then
<step to perform>
fi

4.2 或条件的判断
if [ <judgment condition> -o <judgment condition> ];then
<step to perform>
fi

或者:

if [ <judgment condition> ] || [ <judgment condition> ];then
<step to perform>
fi

补充五:Shell if 可以使用所有 Linux 的 [] 命令和 [[]] 命令的案例作为判断条件

[内容] Linux case 条件判断

内容一:case 语句的格式

case <variable> in
<variable value 1>)
<the command to execute when the variable is this value>;;
<variable value 2>)
<the command to execute when the variable is this value>;;
<variable value 3>)
<the command to execute when the variable is this value>;;
*)
<the command to execute when the variable value is other>;;
esca

内容二:case 语句的使用案例

2.1 直接使用 case 语句的案例

#!/bin/bash

read -p "Which one do you like better, eternalcenter eternalcentre ec-x : " name

case $name in
eternalcenter)
    echo "Do you realy like $name better? eternalcenter?" ;;
eternalcentre)
    echo "Do you realy like $name better? eternalcentre?" ;;
ec-x)
    echo "Do you realy like $name better? ec-x?" ;;
*)
    echo "So you don't like them all ." ;;
esac

2.2 用变量作为条件判断使用 case 语句的案例

#!/bin/bash

read -p "Which one do you like better, eternalcenter eternalcentre ec-x : " name

Variable1=eternalcenter
Variable2=eternalcentre
Variable3=ec-x

case $name in
$Variable1)
    echo "Do you realy like $name better? eternalcenter?" ;;
$Variable2)
    echo "Do you realy like $name better? eternalcentre?" ;;
$Variable3)
    echo "Do you realy like $name better? ec-x?" ;;
*)
    echo "So you don't like them all ." ;;
esac

[命令] Linux 命令 cut (显示文本的列) (转载)

cut命令

cut是一个选取命令,就是将一段数据经过分析取出我们想要的。
语法:Usage: cut OPTION... [FILE]...

选项:
-b,--bytes=LIST:仅显示行中指定直接范围的内容;
-c,--characters=LIST:仅显示行中指定范围的字符;
-d,--delimiter=DELIM:指定字段的分隔符,默认的字段分隔符为“TAB”;
-f,--fields=LIST:显示指定字段的内容;
-n:与“-b”选项连用,不分割多字节字符;
--complement:选项提取指定字段之外的列;
--out-delimiter=<字段分隔符>:指定输出内容是的字段分割符;

补充扩展:
cut命令可以将一串字符作为列来显示,字符字段的记法:
N-:从第N个字节、字符、字段到结尾;
N-M:从第N个字节、字符、字段到第M个(包括M在内)字节、字符、字段;
-M:从第1个字节、字符、字段到第M个(包括M在内)字节、字符、字段。
上面是记法,结合下面选项将每个范围的字节、字符指定为字段:
-b 表示字节;
-c 表示字符;
-f 表示定义字段;

注:cut是竖着切(竖着分割)

[root@iZwz9bhan5nqzh979qokrkZ ~]# cat a.txt 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

实例一:

[root@iZwz9bhan5nqzh979qokrkZ ~]# cat a.txt 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

取出第一列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f 1 a.txt 
root
bin
daemon
adm
lp

取出第一列和第三列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f 1,3 a.txt 
root:0
bin:1
daemon:2
adm:3
lp:4

取出第一列至第三列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f 1-3 a.txt 
root:x:0
bin:x:1
daemon:x:2
adm:x:3
lp:x:4

取出第四列和之前的所有列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f -4  a.txt 
root:x:0:0
bin:x:1:1
daemon:x:2:2
adm:x:3:4
lp:x:4:7

取出第四列和之后的所有列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f 4-  a.txt 
0:root:/root:/bin/bash
1:bin:/bin:/sbin/nologin
2:daemon:/sbin:/sbin/nologin
4:adm:/var/adm:/sbin/nologin
7:lp:/var/spool/lpd:/sbin/nologin

总结:
-d     分界符
-f 1-3 第1列至第3列
-f 1,3 第1列和第3列
-f -3  第3列和之前的内容
-f 3-  第3列号和之后的内容


实例二:

取出除第一列之外的所有列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f 1 --complement a.txt 
x:0:0:root:/root:/bin/bash
x:1:1:bin:/bin:/sbin/nologin
x:2:2:daemon:/sbin:/sbin/nologin
x:3:4:adm:/var/adm:/sbin/nologin
x:4:7:lp:/var/spool/lpd:/sbin/nologin

取出除第一列和第三列之外的所有列
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -d ":" -f 1,3 --complement a.txt 
x:0:root:/root:/bin/bash
x:1:bin:/bin:/sbin/nologin
x:2:daemon:/sbin:/sbin/nologin
x:4:adm:/var/adm:/sbin/nologin
x:7:lp:/var/spool/lpd:/sbin/nologin


实例三:

打印第一个字符到第三个字符
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -c 1-3 a.txt 
roo
bin
dae
adm
lp:

打印前面两个字符
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -c -2 a.txt 
ro
bi
da
ad
lp

打印第五个字符及后面所有的字符
[root@iZwz9bhan5nqzh979qokrkZ ~]# cut -c 5- a.txt 
:x:0:0:root:/root:/bin/bash
x:1:1:bin:/bin:/sbin/nologin
on:x:2:2:daemon:/sbin:/sbin/nologin
x:3:4:adm:/var/adm:/sbin/nologin
:4:7:lp:/var/spool/lpd:/sbin/nologin
————————————————
版权声明:本文为CSDN博主「东城绝神」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_37814112/java/article/details/80492032

注明:所有转载内容皆直接从被转载文章网页的标题和内容的文本中复制而来

CC 4.0 BY-SA 版权协议网址:https://creativecommons.org/licenses/by-sa/4.0/deed.z

站主补充:cut 命令不显示特殊符号

# cut -b2- test.txt

(补充:这里以不显示 test.txt 的特殊符号为例)

[内容] Shell 常用知识 (转载)

shell脚本总结

shell总结

 

shell脚本的本质是shell命令的有序集合

 

建立shell脚本的步骤:建立shell脚本,编写任意多行操作系统命令或shell命令,增加文件的执行权限,结束

 

shell变量

shell允许用户建立变量存储数据,但不支持数据类型。将任何赋给变量的值都解释为一串字符

shell有如下四种变量:用户自定义变量,位置变量,预定义变量,环境变量

 

用户自定义变量:

定义变量:COUNT=1

使用时前面加$:echo $COUNT

删除变量的赋值:unset COUNT

 

位置变量:

$0  与键入的命令行一样,包含脚本文件名

$1,$2...$9  分别包含第一个到第九个命令行参数

$#  包含命令行参数的个数

$@  包含所有命令行参数:“$1,$2...$9 ”

$?  包含前一个命令的退出状态

$*  包含所有命令行参数:“$1,$2...$9 ”

$$  包含正在执行进程的ID号

 

shell环境变量

CDPATH  用于cd命令的查找路径

HOME  用户主目录

PATH  路径

 

shell 程序和语句

shell程序由0到n条shell语句构成,shell语句包括三大类:功能性语句、结构性语句、说明性语句

 

说明性语句:以#开始的部分,不被解释执行

可以出现在程序的任意位置,可以单独一行,也可以接在执行语句的后面

 

功能性语句:任意操作系统命令、shell内部命令、自编程序、等

 

read  从标准输入读出一行,赋给后面的变量

read var   #把读入的数据全部赋给var

read var1 var2 var3     #把读入一行的第一、二个词分别赋给var1、var2,其他的都赋给var3

如果执行read语句时标准输入无数据,则程序在此停留等候,直到数据到来或终止运行

 

expr  主要用于简单的整数运算,包括 +  -  \*  /   %  等

 

 反撇号用于引用命令的运行结果

 

test  用于测试三种对象:字符串、整数、文件属性

可用[  ]代替,注意左右都至少一个空格

如:test  “$answer”  =  “yes”  #变量answer的值是否为字符串yes

test  $num  -eq  18  #变量num的值是否为整数18

test  -d  tmp    #测试tmp是否为一个目录名

 

 

 

结构性语句:条件测试语句、多路分支语句、循环语句、循环控制语句、后台执行语句

条件测试语句

if...then...else...fi

语法结构:

if  表达式

then  

命令表1  #一条或者若干条命令

else

命令表2  #一条或者若干条命令

fi

如果表达式为真,执行命令表1,否则执行命令表2

例子;

if [ -f S1 ]     #测试参数是否为文件

then

echo “File $1 exists”

fi

 

if [-d $HOME/$1]   #测试参数是否为目录

then

echo “File $1 is a directory”

fi

 

 

多路分支语句

case...esac

语法结构:

case 字符串变量  in     #case语句只能检测字符串变量

模式1)

命令表1

;;

模式2)

命令表2

;;

。。。。

*)                  # *表示其他所有

命令表n

;;

esac

例如:

case $1 in

file1)

echo “file1”

;;

file2)

echo “file2”

;;

*)

echo “others”

;;

esac

 

 

循环语句

for...do...done

当循环次数已知或者确定时,使用for循环语句来多次执行一条或一组命令,循环体由do和done来限定

for  变量名  in  单词表

do

命令表

done

说明:变量依次取单词表中的各个单词,每取依次单词,就执行一次循环体,循环次数为单词表中的单词个数,命令表中可以是一条或由分号隔开的多条命令

如果单词表是命令行上的所有位置参数时,可以省去  in  单词表

list=`ls`

for file in $list

do

if[ $1 = $file ]

then

echo “$file found”;

    exit; #退出shell脚本

fi

done

 

while...do...done

语法结构:

while  命令或表达式

do

命令表

done

说明:while首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,知道为假,退出循环

 

until...do...done

语法结构:

until 命令或表达式

do

命令表

done

与上面的相反

 

循环控制语句:

break  和  continue

break n   跳出n层

continue 马上跳转到最近一层循环的下一轮循环

continue  n  转到最近n层循环语句的下一轮循环上

 

 

 

shell函数

shell程序中,常把完成固定功能且多次使用的一组命令封装在一个函数中,每当要使用时,调用函数名即可

函数调用前必须先定义,即顺序上先定义函数,再调用

调用程序可以传递参数给函数,函数可以用return语句把运行结果返回调用程序

函数只在当前shell中起作用,不能输出到子shell中

 

shell函数定义格式

function funtion_name ()   #function可以省掉

{

...

}

 

函数调用方式

value_name = `function_name [arg1 arg2 ...]`    #函数结果返回给变量

或

function_name [arg1 arg2 ...]

echo $?           #获取函数返回的状态

 

函数变量的作用域

全局作用域:在脚本的其他地方都可以访问该变量

局部作用域:只能在声明的作用域内访问

 

局部变量的声明: Local  variable_name = value

 

脚本调试:

跟踪脚本执行结果:

在希望开始调试的地方插入 set -x

在希望结束调试的地方插入 set +x

 

 

---------------------------------------------------------------------

---------------------------------------------------------------------

Bash shell结构

1:shbang行:脚本的第一行,告之内核用哪个shell解释shell脚本,由#!加shell的完整路径组成

2:注释:#后面的为注释,可以在一行后

3:shell通配符或元字符:shell中字符意义比较特殊,如* ? [] > < 2> >> |等,防止这些字符被解释,则必须引用他们

4:局部变量:局部变量作用域在本shell中

5:全局变量:又称为环境变量,由内置的export命令创建,作用域在本shell及子shell中

6:提取变量值:$

7:参数:可以从命令行传递参数给脚本

8:命令替换:`A` $(A)  结果可以赋给一个变量或代替所在位置

---------------------------------------------------------------------

正则表达式

正则表达式是一种字符模式,在查找过程中匹配指定的字符,可以用特殊的元字符来控制它们,正则表达式都被置于两个正斜杠//之间

元字符:表达的是不同于字符本身的含义

本书中的元字符有两类:shell元字符、正则表达式元字符,它们各司其职,shell元字符是由shell解析的,就是下面所讲的文件名置换;正则表达式元字符是由各种执行模式操作的程序来解析的,如vi、grep、sed、awk

---------------------------------------------------------------------

正则表达式元字符:

^  行首定位

$  行尾定位

.  匹配单个字符

*  匹配0或多个重复的位于*前的字符

[]  匹配指定组字符中的任意一个 ;如[LlT]

[-] 匹配指定范围内的字符 ;如[x-yA-Z0-8]

[^] 匹配不在指定组内的字符

[^ - ]跟上面的相反

\  转移跟在后面的字符     #转义元字符,使之不被解释

\< 词首定位符     #定位以什么开头的词

\> 词尾定位符     #定位以什么结尾的词

---------------------------------------------------------------------

grep 家族

grep家族由grep、egrep、fgrep组成 

grep命令在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行

一般格式:grep  [选项]   基本正则表达式  [文件]   

选项:-n 显示行号  -i 大小写不敏感  -w表达式作为词来查找,也就是不是一个词的一部分  -r 递归查找

基本正则表达式:可为字符串,如果为字符串,最好用“”如果是模式匹配,用‘’调用变量时,也应该使用“”

文件:可以为多个文件;如 A1 A2

常用举例子

grep -n “your” www    #文件www中查找含有your单词的行,且输出行号

grep -nw “your” www    #文件www中查找含以your做单词的行,且输出行号

grep -nr ‘[a-zA-Z0-9].you’ ./  #递归./ 中查找含有以a-z A-Z 0-9开始的单词的行,且输出行号

---------------------------------------------------------------------

find命令及xargs

find pathname -options [-print -exec -ok]

常用的options为name 此时记住要用引号将文件名模式引起来

find ./  “*org.txt”   #在当前目录及子目录中寻找以org.txt结尾的文件

find 找到文件后可用xargs对其操作

find ./  “*org.txt” | xargs ls

find ./  “*org.txt” | xargs grep “device”  #在结果中搜索device

---------------------------------------------------------------------

启动

系统启动后

->init->getty进程

->/bin/login  初始化环境,启动shell

->/bin/bash 执行/ect/profile,执行~/.bash_profile ~/.bash_login ~/.profile,执行~/.bashrc

->等待用户输入

---------------------------------------------------------------------

环境

一个进程的环境包括:变量等,它定义了可以从一个进程继承到下一个进程的特性

用户的shell配置定义在shell初始化文件中,bash shell有许多启动文件,这些文件可以执行source命令,对一个文件执行source命令会使得这个文件中的所有设置称为当前shell的一部分,也就是说不会创建子shell

登陆时,会执行~/.bash_profile文件执行source命令,如无,则source ~/.bash_login,若无,则source ~/.profile,这三个文件只能source一个,再source ~/.bashrc

~/.bashrc:包含特定的变量和别名,当一个新的bash shell启动或bash脚本启动时会自动执行source ~/.bashrc

在当前提示符下输入shell或bash启动的是子shell

/etc/bashrc:系统级的函数和别名可以在/etc/bashrc文件中设置,主提示符一般在这设置

~/.profile:是一个用户定义的初始化文件,它是被Bourne shell使用的,因此不能包括对bash shell的特定设置,运行bash时只有没找到其他文件时才source此文件,它允许用户定制和修改shell环境,也可以放应用程序的初始化

---------------------------------------------------------------------

source命令或dot命令(.)  和  ./命令

source命令式内置的bash命令,来自C shell

dot命令也就是. 来自Bourne shell

二者完全一样,都是一个脚本名作为参数,shell将在当前的shell环境中执行这个脚本,也就是不启动子shell,脚本中的设置的所有参数将成为当前shell环境的一部分。

./执行脚本时是创建子shell,脚本中的设置参数在脚本退出后就无效了。

 

例子:在家目录下的.bashrc中加入WANG=”ni hao”

然后. .bash.rc

此时执行内容为 echo “$WANG”的 脚本

 

如用 ./sh.sh 则无输出  #./执行时是在起一个子shell

如用source sh.sh或 . sh.sh则输出ni hao  #source是在本shell中执行

---------------------------------------------------------------------

bash shell元字符(通配符)

\  按字面含义解释后面的那个字符

&  在后台处理的进程

; 分隔命令

$  替换命令

*  匹配任意字符

?  匹配任意单个字符

[...] 匹配[]中的任意一个字符

[!...] 不匹配[]中!的任意一个字符

(cmds)  在子shell中执行命令

{cmds}  在当前shell中执行命令

---------------------------------------------------------------------

文件名置换

计算命令行时,shell会用元字符来缩写能够匹配某个特定字符组的文件名或路径名

将元字符展开为文件名或路径名的过程称为文件名替换或globbing

*    匹配文件(夹)名中的任意字符串

如:ls app*

cd cmdd*

?    匹配文件(夹)名中的任意一个字符

[...] 匹配[]中的任意一个字符

[!...] 不匹配[]中!的任意一个字符

如:ls [a-z]*.o   #匹配以a-z开头的已.o结尾的文件

ls [!0-9]*.o     #匹配以非0-9开头的已.o结尾的文件

---------------------------------------------------------------------

命令执行顺序

命令1 && 命令2  #命令1执行成功才会执行命令2

命令1 || 命令2  #命令1执行不成功才会执行命令2

用() 和 {}将命令结合在一起

 

 

---------------------------------------------------------------------

Bash shell变量

变量可分为两种:局部变量和环境变量

局部变量只在创建他们的shell中可用,环境变量作用域可以扩展到子shell中去

变量命名规则:可以是字母、0-9、下划线组成,必须以字母或下划线开头,其他字符都标志着变量名的终止,变量名大小写敏感

有两个内置命令可以用来创建变量,他们是declare、typset,其选项可以控制变量的设置方式,建议使用declare.

格式:declare  [选项]  变量=值

选项:-x  将变量设置成环境变量

      -r 将变量设置成只读变量

      -a 将变量当一个数组

---------------------------------------------------------------------

创建局部变量

1:变量赋值:变量=值    #注意等号周围不能有任何空白字符,如果想赋空,可以在等号后跟上换行符

2:内置命令declare  变量=值  #注意等号周围不能有任何空白字符,如果想赋空,可以在等号后跟上换行符

例子:

设置:round=world 或 round=”world nice”  #“”保护空白符

设置:declare round=world

输出:echo $round

设置:file.bak=”xxxx”   错,变量名中出现非法字符

local函数:函数内创建局部变量可以用local函数

---------------------------------------------------------------------

创建环境变量

环境变量,又被称为全局变量,作用域可以扩展到子shell中,通常环境变量用大写

环境变量是已经用export内置命令导出的变量,如果想设置环境变量,只需在设置变量时或赋值后使用export命令即可,declare 带-x也是设置环境变量

设置环境变量:

1:export 变量=值  #注意等号周围不能有任何空白字符,如果想赋空,可以在等号后跟上换行符

2:变量=值; export 变量    #注意等号周围不能有任何空白字符,如果想赋空,可以在等号后跟上换行符  

3:declare -x 变量=值  #注意等号周围不能有任何空白字符,如果想赋空,可以在等号后跟上换行符

---------------------------------------------------------------------

设置只读变量

只读变量是不能被重新定义或复位的特殊变量,但是如果使用declare定义的变量,可以重定义,不能复位

设置:name=”TOM”

readonly name   #设置只读

unset name  #不能复位

name=Jem  #不能重定义

设置:declare -r city=”shanghai”

unset city #不能复位

declare city=“beijin” #可以

---------------------------------------------------------------------

提取变量的值

在变量前加$

---------------------------------------------------------------------

复位变量

只要不被设置只读,局部变量和环境变量都可以用unset命令复位

格式:unset 变量名

---------------------------------------------------------------------

显示变量值

1:echo [选项]  变量   #echo将他的参数显示到标准输出上

选项:-e   #允许解释转义字符,如echo -e “\a”  \a转义为报警

如:echo The name is $NAME

echo -e “\a”  #报警

2:printf命令

---------------------------------------------------------------------

变量扩展修饰符

可以用一些专用修饰符来测试和修改变量,修饰符首先进行简单的条件测试,检查某变量是否已被设置,然后根据测试结果给变量赋值

${VA:-word}  #如变量VA已经设置且非空,则代入其值,否则代入word   临时替换默认值 

${VA:=word}  #如变量VA已经设置且非空,则代入其值,否则VA设置为word,代入VA永久替换默认值

${VA:+word}  #如变量VA已经设置且非空,则代入word,否则代入空值   临时替换默认值

${VA:?word}  #如变量VA已经设置且非空,则代入其值,否则输出word且从shell退出  基于默认值创建错误信息

 

注:不加冒号时,值为空也被认为已经设置

如:echo ${name-Joe}  #结果为空

echo ${name:-Joe}  #结果为Joe

echo ${namex:?”namex is undefined”}  

echo ${y?}  #如果y未设置,否则输出parameter null or not set

 

${VA:offset}  #获取变量VA值中位置从offset开始的字串

${VA:offset:length}  #获取变量VA值中位置从offset开始长度为length的字串  创建字串

如:var=notebook

echo ${var:0:4}   #结果note

---------------------------------------------------------------------

子串的变量扩展

模式匹配变量用来在串首或串尾截掉串的一部分,常用语删除路径名的头或尾

${变量%模式}  #将变量值的尾部与模式进行最小匹配,并将匹配到的部分删除

${变量%%模式} #将变量值的尾部与模式进行最大匹配,并将匹配到的部分删除

${变量#模式}  #将变量值的头部与模式进行最小匹配,并将匹配到的部分删除

${变量##模式} #将变量值的头部与模式进行最大匹配,并将匹配到的部分删除

${#变量}      #替换为变量中的字符个数,如果是*或@ ,长度则是位置参量的个数

如:

pathname=”/usr/bin/local/bin”

echo ${pathname%/bin*}  #结果/usr/bin/local/

echo ${pathname%%/bin*}  #结果/usr

echo ${pathname#/usr}  #结果/bin/local/bin

echo ${pathname##/usr}  #结果bin

echo ${#pathname}  #结果8

---------------------------------------------------------------------

位置参量

下面这组专用内置变量常称为位置参量,通常被shell脚本用来从命令行接受参数,或被函数用来保存传递给它的参数

$0  #指当前shell脚本的名称

$1-$9  #代表第一个到第9个位置参量

${10} ${11} #第10、11个位置参量,不用$10,$11

$#  其值为位置参量的个数,不含$0

$*  其值为所有的位置参量

$@  同$*

“$*”  其值为“$1 $2 $3”

“$@”  其值为“$1”“$2”“$3”

位置参数可以用set命令来设置、重置或复位

set --   #清除所有的位置参数

---------------------------------------------------------------------

其他特殊变量

$    #当前shell的pid

_    #当前sh的选项设置

?    #已执行的上一条命令的退出值

!    #最后一个进入后台的作用的pid

---------------------------------------------------------------------

引用

用来保护特殊的元字符不被解释和禁止参量扩展

引用有三种方式:反斜杠、单引号、双引号

需要引用的特殊元字符有:

;

&

()

{}

|

< > 

空格 tab 换行符

$ 

* [] ? 

1:单引号和双引号必须成对出现

2:单引号保护特殊元字符免受解释,双引号也能,但双引号允许处理变量替换字符$和命令替换字符``和\

3:双引号可以保护单引号,单引号可以保护双引号

4:如果有不匹配的引号,bash会出现次提示符

反斜杠:反斜杠用于引用(或转义)单个字符,使其免受解释。

单引号中的反斜杠不会被解释

如果在双引号中,反斜杠将保护$ ``和反斜杠免受解释

单引号:成对出现,保护所有元字符不被解释,打印双引号就必须用双引号将其括起来,或反斜杠转义

双引号:同单引号,但是允许进行变量替换$和命令替换``和\

 

简言之:单引号中什么都不被解释。双引号中$ `` \这三个会被解释,如不想解释用\转义

注意:``同$()是一样的,所以$(date)也会展开

---------------------------------------------------------------------

命令替换

命令替换的用处是将命令的输出结果赋给一个变量或将命令的输出结果代入命令所在位置

bash 允许使用两种格式:`命令`   和  $(命令)

执行扩展时,bash先执行命令,然后返回命令的标准输出,输出结果末尾的换行符都将被删除,如果不想删除,可用“”括起,如:echo “$(cal)”

如:echo “this is `date +%H`”   #this is 09

d=$(date)  #d存放命令date的结果

`命令`  \保留字面意思,除非后面跟$ ` \ 且``中$  \生效,可用\转义之,``中再有``的话必须用\转义

$(命令)  中的所有特殊字符都不会解释

命令替换可以被嵌套,``必须使用\`转义,如echo `basename \`pwd\` `  #其中转义后的`pwd`也是当做命令替换的,如:$(basename $(pwd))

---------------------------------------------------------------------

数组

bash 中可以创建一维数组,数组允许将一列词放到一个变量名中,可以用内置命令declare -a创建,或直接给变量名一个下标来创建,如x[0]=5   索引值为从0开始的整数,数组无上限,索引也不必是有序数。

取出数组中某个元素,语法为:${数组名[索引]}

创建数组:

declare 、local 、read-only内置命令也可以带-a选项来声明一个数组。read -a是读取一列词到数组中

declare -a va_name=(item1 item2 item3 ...)

declare -ar va = {item1 item2 item3 ...}

states=(ME [3]=CA [2]=CT)  #数组states第0元素为ME  3元素为CA  2元素为CT

declare -a nums=(45 33 100 65)

name=(TOM Dick Harry)

echo ${va_name[*]}   #输出数组所有元素

echo ${#va_name[*]}  #输出数组大小

取消定义:unset name 或 unset name[2]

---------------------------------------------------------------------

函数

bash函数用于在当前shell环境(不派生子shell)通过函数名执行一组命令,函数常常用于提高脚本的模块化程度。

函数可被重复调用。函数必须定义后才会被调用

定义函数:有两种格式声明一个bash函数

1:函数名后跟一对圆括号,再跟函数定义

function_name () { commands;commands; }

2:function关键词后跟函数名及函数定义,圆括号可选

function function_name { commands;commands;}

function function_name () { commands;commands;}

注意:命令之间用;隔开,最有一条命令必须以分号终结。花括号两侧空格是必须的。

传递给函数的任何参数被当做函数内的位置参数,一个函数的位置参数相对于函数来说是局部的

内置命令local允许在函数定义中创建局部变量

 

函数可以递归调用本身

函数中的命令是在当前shell环境下执行

全局函数:同变量一样,函数作用域可以扩展到子shell,只要用export -f全局化函数

export -f 函数名

说明:当函数命令列在单独的行,可以不用分号,最后一条还是需要。如果列在同一行,必须用分号隔开

如:function welcome { echo “Hi $1 and $2”; }

welcome tom joe  #传递参数给函数,结果为Hi tom and joe

set jane anna lizzy

echo $1 $2

jane anna

unset -f welcome #清除函数定义

 

列出和清除函数

declare -f #列出该shell中定义的所有函数及他们的定义

declare -F #同上,只列出函数名

unset -f   #清除函数定义

---------------------------------------------------------------------

管道

管道(pipe)将管道符左侧命令的输出作为到管道符右侧命令的输入,一条管道线可能不止一个管道

管道符用竖杠 | 表示,一般形式:命令1 | 命令2 | 命令3

---------------------------------------------------------------------

shell内置命令

shell中有许多内置到它的源码中的命令,shell无需到磁盘中定位他们,执行速度速度快很多。

常见内置命令如下:

:   #空命令

.   #在当前进程的环境下执行程序,同source

alias #命令重命名

unalias #删除重命名

bg  #将作业放到后台

cd 

exit

fg #将作业放到前台

jobs #列出放在后台的作业

set #设置选项和位置参数

unset #删除变量值或函数

declare

export

---------------------------------------------------------------------

Bash shell编程

shell脚本:当命令不在命令行上执行,而是通过一个文件执行时,该文件被称为shell脚本,脚本以非交互的方式运行。它先查找环境变量所指定的环境文件,通常为.bashrc,然后从该文件开始执行,然后才开始执行脚本中的命令

创建shell脚本的步骤:

1:第一行:#!/bin/bash

2:编写内容

shell脚本结构:由一组Unix/linux命令、bash shell命令、程序结构控制语句、注释 组成

3:增加执行权限  chmod +x files

---------------------------------------------------------------------

读取用户输入

read命令

read是一个内置命令,用于从终端或文件读取一个输入行,直到换行符,行尾的换行符被转换成一个空字符,如果后面未跟变量名,则读取的行被赋给内置变量REPLY,可以用read中断脚本的运行,直至输入回车键

read var                 #把读入的数据全部赋给var

read var1 var2 var3     #把读入一行的第一、二个词分别赋给var1、var2,其他的都赋给var3

---------------------------------------------------------------------

算术运算

整数运算(declare和let命令)

declare命令:可以用declare -i 定义整形变量,如果给一个整形变量赋一个字符串,则bash将把变量赋值为0,可以对已定义的整形变量执行算术运算(如果未定义为整形变量,内置的let命令也允许算术操作),如果给整形变量赋一个浮点数值,则bash报语法错误。数字可以用不同基数的数字表示

如:declare -i num

num=5 + 5 #错

num=5+5  #对

num=”5 + 5” #对

num=5.6 #错

 

declare -i  将列出所有已经设置的整形变量及其值

 

用不同的基数表示数字

格式:variable=base#number

如:declare -i x=017

x=2#101

x=8#17

let命令:let命令式bash shell内置命令,用来执行整形算术运算和数值表达式测试;可用(())表示let命令

let命令在执行算术运算时,不需要用$来展开变量,参数含有空格则用“”包含

如:let “i = i + 2”

---------------------------------------------------------------------

位置参数

用户可以通过命令行向脚本传递信息,跟在脚本名后的用空白符分隔的每个词都称为参数,可以在脚本中使用位置参数来引用命令行参数

shell环境中的位置参数作用域在本shell,shell脚本执行时跟在后面的参数相当于局部的位置参数,只对本脚本生效

如:脚本内容 echo “$1”

执行时 source sh.sh wang  #则输出wang

如果在命令行set hahaha

执行时 source sh.sh wang  #则输出wang

执行时 source sh.sh  #则输出hahaha

 

set命令与位置参数

可以用set命令设置或重设位置参数

带参数的set命令将重置位置参数,重置的是shell环境中的位置参数。清除所有位置参数,可以用set -- 命令

---------------------------------------------------------------------

条件结构和流程控制

条件结构能够根据某个特定的条件是否满足,来执行相应的任务

bash可以检测两种类型条件:命令成功或失败,表达式为真或假。在任何一种类型的测试中,都要使用退出状态,为0表示命令成功或表达式为真,非0表示命令失败或表达式为假。退出状态保存在状态变量?中
简言之:bash中执行命令成功与否和表达式为真或假都会改变退出状态变量?

 

 

内置命令test

单方括号的test命令:通常使用内置的test命令测试表达式的值,test命令可以被链接到方括号上,这样即可使用单独的test命令,也可通过把表达式用单括号括起来,来测试表达式的值

用test命令或[]测试表达式时,表达式中的shell元字符不会被解释。由于对变量进行单词分离,因此包含空白符的字符串必须用引号括起来

双方括号的test命令:用[[]]来测试表达式的值,其中对变量不进行单词分离,但可以通过元字符扩展进行模式匹配。包含空白符的字符串必须用引号括起来,如果一个字符串(不管含不含空白符)仅仅是在表达式中作为一个普通字符串,而不是一个模式的一部分,则必须用引号括起来

逻辑操作符&&、||代替了与test命令一起使用的-a -o选项

 

说明:test可以用来测试字符串、数字、文件。test命令中表达式等号两侧必须有空格。单方括号第一个方括号后必须有空格,表达式两侧必须有空格。

简言之:

[]的测试表达式:表达式可为字符串比较、数字比较、文件测试。表达式等号两侧必须有空格,方括号必须有空格。表达式中的shell元字符不会被扩展。对变量进行单词分离,所以包含空格时必须用引号括起来

[[]]的测试表达式:表达式可为字符串比较、数字比较、文件测试。表达式等号两侧必须有空格,方括号必须有空格。表达式支持shell元字符,如果为普通字符串,防止误认为模式,必须用双引号括起来。支持逻辑&& || ,对应test中的-a -o   ,其中对变量不进行单词分离,即使变量由多个词组成也不需要双引号括起来

 

let和带双圆括号的算术运算符(())

对于计算算术表达式,可以不用test而用let命令,let命令含有丰富的操作符,let命令等同(())

(())中的变量不需要使用$,操作符两侧必须空格,圆括号两侧必须空格

简言之:let命令更适合整形算术运算和数值表达式测试

---------------------------------------------------------------------

if命令

if 结构后面的命令可以是bash内置命令或可执行程序,如ls

bash shell中跟在if后面的则是一条或一组命令。

 

exit 命令和变量?  exit用于终止脚本并返回到命令行

检查空 检查变量的值是否为空时,必须用双引号把空括起来,否则test命令失败

 

if 命令

then

命令

elif 命令

then

命令

elif 命令

then

命令

fi

---------------------------------------------------------------------

null命令(shell内置命令)

:代替null命令

null命令不做任何事,只是返回退出状态0(注意没退出,不同于exit 0)

---------------------------------------------------------------------

case命令

格式:

case 变量 in

表达式1)

命令组

;;

表达式2)

命令组

;;

...

*)

命令组

;;

esac

变量的值逐一与表达式相比,符合则执行命令组,并跳到esac后继续执行

表达式可以使用shell通配符,还可以使用 | 将两值相或

---------------------------------------------------------------------

循环命令

bash shell提供三种类型的循环:for   while   until

---------------------------------------------------------------------

for命令

格式:

for  变量  in   词表

do

命令组

done

注:词表可以通过执行命令获得,如  for  W  in $(date)

词表支持shell元字符:如 for file in memo[1-5]  

注意词表是$* $@ “$*” “$@”时的区别

如果没有“in 词表”则相当于“ for 变量 in $* ”

如果命令行参数为*,则它表示当前目录下的所有文件。

---------------------------------------------------------------------

while命令

格式:

while 测试命令

do

命令(命令组)

done

注:while 后的测试命令可以用test 或let或其他

---------------------------------------------------------------------

until命令

同while命令,只不过相反,也就是until 后的命令执行不成功时执行命令组

---------------------------------------------------------------------

循环控制命令

shift命令

shift 命令将参数左移指定次数,如:shift 5,没给参数时移动一次,当不够移动时,输出信息。

shift常用于while循环中遍历位置参数列表时。

如:while (( $# > 0 ))

do

echo $1   #$1值不断变化

shift

done

 

ture命令:总是已状态0退出

 

break命令

break用于跳出循环,层数为跳出几层

continue命令 跳过本次循环,继续下次,参数为调到哪一层循环起点,默认为跳到最近一层

---------------------------------------------------------------------

I/O重定向 与 子shell

shell可通过管道或重定向将输入从文件输入改为从循环读取输入,输出到循环改为输出到文件

shell启动一个子shell来处理I/O重定向和管道,循环结束后,在循环中定义的所有变量对脚本的其余部分都是不可见的

重定向一般是到文件,管道一般是到命令

将循环的输出重定向到一个文件:bash循环的输出不仅可以送到标准输出,还可以通过管道送到文件

将循环的输出管道到一个命令

---------------------------------------------------------------------

后台执行循环

循环可以在后台执行,这样就可以继续往下执行其他程序而不必等待循环处理全部完成

---------------------------------------------------------------------

函数

函数在当前环境中运行,函数共享调用它的脚本中的变量,还允许给函数传递参数,可以使用local功能在函数内部创建局部变量

在函数中调用exit将退出整个脚本。

函数中的return语句,返回函数执行的最后一条命令的退出状态,或返回指定参数值

使用export -f把函数导出到子shell

使用declare -f可以列出所有的函数名及其定义

如果函数保存在其他一些文件中,可以用source和dot命令把他们载入到当前脚本中

函数可以递归调用,次数没限制

 

清除函数

从内存中清除某个函数,使用unset命令

unset 函数名

 

函数的参数和返回值

当前shell环境中的变量对函数是可见的,在函数中对环境所做的任何改动也是会对shell环境生效的。

函数可以使用位置参数向函数传递参数,位置参数是函数私有的,也就是说,函数对参数的操作不会影响在函数外使用的任何位置参数

内置local功能:函数私有的局部变量,在函数退出后随即消失。

内置return命令:用来退出函数并将控制回转到程序调用函数的位置,如果未给return赋值,则返回最后一条命令的退出状态,如果赋值了,则该值保存在变量?中。可以是0-255之间整数。

获取函数的结果可以用 命令替换,如:$(函数名)  `函数名`

函数可以定义在文件中,当需要时,调用source或dot命令跟上函数名就能激活文件中的函数,函数会被加载到shell内存空间

---------------------------------------------------------------------

调试

带-n选项的bash命令,能对脚本进行语法检查,但不去运行任何一条命令,如语法错误,则报错,否则不显示任何内容

最常见的调试脚本的手段是用带-x选项的set命令,或是调用带-x选项和脚本名为参数的bash

此时shell对脚本的每条命令处理过程为:先执行替换,接在显示,再去执行它。shell显示脚本中的行时,会在行首添加加号+

调试选项:

bash -x 脚本名  #回显   在变量替换之后,执行命令之前,显示脚本的每一行

bash -v 脚本名  #详细   在执行之前,按输入的原样打印脚本中的各行

bash -n 脚本名  #不执行 解释但不执行命令

set -x  #打开回显  跟踪脚本执行

set +x  #关闭回显  关闭跟踪功能

---------------------------------------------------------------------

调试shell脚本

风格问题

1:加注释

2:定义有意义的变量名

3:确保健壮性

错误类型

---------------------------------------------------------------------
————————————————
版权声明:本文为CSDN博主「wangchaoqun1997」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangchaoqun1997/article/details/36480131

注明:所有转载内容皆直接从被转载文章网页的标题和内容的文本中复制而来

CC 4.0 BY-SA 版权协议网址:https://creativecommons.org/licenses/by-sa/4.0/deed.z