1. shell中可用正则表达式的命令
grep、awk、sed等命令可以使用正则表达式;
ls、find、cp等命令不支持正则表达式,只能使用通配符。
正则表达式(regular express)基本上是一种“表示法”,他是以行为单位来进行字符串的处理行为。只能使用在
支持它的工具程序(如vi、grep、awk、sed中)。正则表达式与shell通配符的关系就像是局部变量和全局变量的
关系(即以后遇到一个命令如果支持正则表达式,则通配符概念抛弃。否则使用通配符)。
2. Bash shell特殊符号
1)防止扩展符号
" " 防止通配符扩展
在双引号中的特殊符号都没有特殊含义,但是"$"、"`"和"\"例外,分别拥有“调用变量值”、“引用命令”
和“转义符”的特殊含义。
' ' 防止通配符、变量调用符、引用命令符和转义符扩展
在单引号中的所有特殊符号,包括"$"、"`"和"\"都没有特殊含义。
\ 转义符
跟在转义符\之后的特殊符号将失去特殊含义,变为普通字符。如 \$ 将输出 $ 符号,而不当做变量引用。
2)命令替换符号
$( ) 括号中的内容为系统命令,在Bash中会先执行。
` ` 与$( )作用一样,但不推荐使用,因为容易混淆、看错。
由命令替换符引申说明一下算数运算:
① $((运算式))
举例:r=1
r=$(($r+1)) 或 ((r=$r+1))
② $[运算式]
举例:r=1
r=$[$r+1]
③ $(expr 运算式) --- 本质就是通过命令替换符$()调用算术命令
举例:r=1
r=$[$r+1]
④ `expr 运算式` --- 本质就是通过命令替换符` `调用算术命令
举例:r=1
r=`expr $r + 1` #运算符前后要有空格
⑤ let 运算式
举例:r=1
let r=r+1
3)其它特殊符号
$ 用于调用变量的值
[] testing
(()) testing
因为空格在linux中时作为一个很典型的分隔符,比如string1=this is astring,这样执行就会报错。
为了避免这个问题,因此就产生了单引号和双引号。
它们的区别在于,单引号将剥夺其中的所有字符的特殊含义,而双引号中的$(参数替换)和
`(命令替换)是例外。所以,两者基本上没有什么区别,除非在内容中遇到了参数替换符$和
命令替换符`。
例如:
num=3
echo ‘$num’
$num
echo “$num”
3
所以,若在双引号””里面使用这两种符号,就要用反斜杠\进行转义。
2. 反引号``
与$()是一样的,均为命令替换符。
在执行一条命令时,会先将其中的``,或者是$()中的语句当作命令执行一遍,然后再将结果加入
到原命令中重新执行,例如:
echo `ls`
会先执行 ls 得到xx.sh等,再替换原命令为:
echo xx.sh
最后执行结果为
xx.sh
因此,平时我们遇到的把一堆命令的执行结果输出到一个变量中,需要用这个命令替换符括起来,
也就可以理解了。
这里又涉及到了一个问题,虽然不少系统工程师在使用替换功能时,喜欢使用反引号将命令括起来。
但是根据POSIX规范,要求系统工程师采用的是$(命令)的形式。所以,我们最好还是遵循这个规范,
少用``,多用$()。
3. 双括号(())
linux下shell中(())双括号运算符的使用详解:
在学习使用shell的逻辑运算符”[]”使用时候,必须保证运算符与算数之间有空格。
四则运算也只能借助let,expr等命令完成。 而双括号(())结构语句,就是对shell中算数及赋值运算的扩展。
使用方法:
语法:((表达式1,表达式2…))
特点:
1)在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。
2)在双括号结构中,所有变量可以不加入$符号前缀。
3)双括号可以进行逻辑运算,四则运算
4)双括号结构 扩展了for,while,if条件测试运算
5)支持多个表达式运算,各个表达式之间用逗号,分开
6)$(()),即双括号前带$,可将获得表达式值赋给左边变量
实例1(扩展四则运算)
#!/bin/sh
a=1
b=2
c=3
((a=a+1))
echo $a
a=$((a+1,b++,c++))
echo $a,$b,$c
运行结果:
sh testsh.sh
2
3,3,4
双括号结构之间支持多个表达式,然后加减乘除等c语言常用运算符都支持。
如果双括号前带$,将获得表达式值,赋值给左边变量。
实例2(扩展逻辑运算)
#!/bin/sh
a=1
b="ab"
echo $((a>1?8:9))
((b!="a"))&& echo "err2"
((a<2))&& echo "ok"
运行结果:
sh testsh.sh
9
err2
ok
实例3(扩展流程控制语句-逻辑关系式)
代码如下:
#!/bin/sh
num=100;
total=0;
for((i=0;i<=num;i++));
do
((total+=i));
done
echo $total;
total=0;
i=0;
while((i<=num));
do
((total+=i,i++));
done
echo $total;
if((total>=5050));then
echo "ok";
fi
运算结果:
sh testsh.sh
5050
5050
ok
有了双括号运算符后,[[]]、[]、test 逻辑运算、let、expr就不是必须的了。
4. $()和${}和$(())和(())
4.1 $()和${}的用法
$( )与` `反引号都是用来做命令替换用command substitution的。
${ } 其实就是用来作变量替换用。一般情况下,$var 与 ${var} 并没有区别。
但是用 ${ } 会比较精确的界定变量名称的范围。
举例:
var=123
echo $var #输出:123
echo $varabc #error
echo ${var}abc #输出:123abc
echo {$var}abc #输出:{123}abc
这里再用一些例子加以说明 ${ } 的一些特异功能:
假设我们定义了一个变量为:
file=/dir1/dir2/dir3/my.file.txt
我们可以用 ${ } 分别替换获得不同的值:
${file#*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt
${file#*.}:拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}:拿掉最后一个 . 及其左边的字符串:txt
${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}:拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
# 是去掉左边(在鉴盘上 # 在 $ 之左边)
% 是去掉右边(在鉴盘上 % 在 $ 之右边)
单一符号是最小匹配﹔两个符号是最大匹配。
${file:0:5}:提取最左边的 5 个字节:/dir1
${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2
我们也可以对变量值里的字符串作替换:
${file/dir/path}:将第一个 dir 提换为 path:/
path1/dir2/dir3/my.file.txt
${file//dir/path}:将全部 dir 提换为 path:/
path1/path2/path3/my.file.txt
利用 ${ } 还可针对不同的变量状态赋值(没设定、空值、非空值):
${file-my.file.txt} :假如 $file 没有设定,则使用 my.file.txt 作传回值。
(空值及非空值时不作处理)
${file:-my.file.txt} :假如 $file 没有设定或为空值,则使用my.file.txt
作传回值。 (非空值时不作处理)
${file+my.file.txt} :假如 $file 设为空值或非空值,均使用my.file.txt作
传回值。(没设定时不作处理)
${file:+my.file.txt} :若 $file 为非空值,则使用 my.file.txt 作传回值。
(没设定及空值时不作处理)
${file=my.file.txt} :若$file没设定,则使用 my.file.txt 作传回值,同时
将$file赋值为 my.file.txt 。(空值及非空值时不作处理)
${file:=my.file.txt} :若$file没设定或为空值,则使用my.file.txt作传回值,
同时将 $file 赋值为my.file.txt 。(非空值时不作处理)
${file?my.file.txt} :若 $file 没设定,则将 my.file.txt 输出至STDERR。
(空值及非空值时不作处理)
${file:?my.file.txt} :若 $file 没设定或为空值,则将 my.file.txt 输出至
STDERR。(非空值时不作处理)
以上的理解在于, 你一定要分清楚 unset 与 null 及 non-null 这三种赋值状态.
一般而言,:与null有关,若不带:的话,null 不受影响,若带:则连null 也受影响.
还有,${#var} 可计算出变量值的长度:
${#file} 可得到 27 ,因为 /dir1/dir2/dir3/my.file.txt 刚好是 27 个字节
4.2 $(())的用途
$(())是用来做整数运算的。
在 bash 中,$(( )) 的整数运算符号大致有这些:
+ - * / :分别为 "加、减、乘、除"。
% :余数运算
& | ^ !:分别为 "AND、OR、XOR、NOT" 运算。
举例:
wangnc>a=5;b=7;c=2;
wangnc>echo $a + $b
5 + 7
wangnc>echo $(( a + b*c))
19
wangnc>echo $(((a*b)/c))
17
wangnc>echo $(($a +$b*$c))
19
wangnc>
在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用,如:
$(( $a + $b * $c)) 也可得到 19 的结果
此外,$(( )) 还可作不同进位(如二进制、八进位、十六进制)作运算呢,只是,输出结果皆为十进制而已:
echo $((16#2a)) 结果为 42 (16进位转十进制)
4.3 (())的用途
事实上,单纯用 (( )) 也可重定义变量值,或作 testing:
a=5; ((a++)) 可将 $a 重定义为 6
a=5; ((a--)) 则为 a=4
a=5; b=7; ((a < b)) 会得到 0 (true) 的返回值
常见的用于 (( )) 的测试符号有如下这些:
< 小于
> 大于
<= 小于或等于
>= 大于或等于
== 等于
grep、awk、sed等命令可以使用正则表达式;
ls、find、cp等命令不支持正则表达式,只能使用通配符。
正则表达式(regular express)基本上是一种“表示法”,他是以行为单位来进行字符串的处理行为。只能使用在
支持它的工具程序(如vi、grep、awk、sed中)。正则表达式与shell通配符的关系就像是局部变量和全局变量的
关系(即以后遇到一个命令如果支持正则表达式,则通配符概念抛弃。否则使用通配符)。
2. Bash shell特殊符号
1)防止扩展符号
" " 防止通配符扩展
在双引号中的特殊符号都没有特殊含义,但是"$"、"`"和"\"例外,分别拥有“调用变量值”、“引用命令”
和“转义符”的特殊含义。
' ' 防止通配符、变量调用符、引用命令符和转义符扩展
在单引号中的所有特殊符号,包括"$"、"`"和"\"都没有特殊含义。
\ 转义符
跟在转义符\之后的特殊符号将失去特殊含义,变为普通字符。如 \$ 将输出 $ 符号,而不当做变量引用。
2)命令替换符号
$( ) 括号中的内容为系统命令,在Bash中会先执行。
` ` 与$( )作用一样,但不推荐使用,因为容易混淆、看错。
由命令替换符引申说明一下算数运算:
① $((运算式))
举例:r=1
r=$(($r+1)) 或 ((r=$r+1))
② $[运算式]
举例:r=1
r=$[$r+1]
③ $(expr 运算式) --- 本质就是通过命令替换符$()调用算术命令
举例:r=1
r=$[$r+1]
④ `expr 运算式` --- 本质就是通过命令替换符` `调用算术命令
举例:r=1
r=`expr $r + 1` #运算符前后要有空格
⑤ let 运算式
举例:r=1
let r=r+1
3)其它特殊符号
$ 用于调用变量的值
[] testing
(()) testing
3. 其它
shell中字符串比较可以用“==”,也可以用“=”,比如 a="ABC"; [ $a == "ABC" ] 或 [ $a = "ABC" ]
以下为从网上收集的一些相关的详细说明:
====================================================================================
1. 单引号' '和双引号" "
因为空格在linux中时作为一个很典型的分隔符,比如string1=this is astring,这样执行就会报错。
为了避免这个问题,因此就产生了单引号和双引号。
它们的区别在于,单引号将剥夺其中的所有字符的特殊含义,而双引号中的$(参数替换)和
`(命令替换)是例外。所以,两者基本上没有什么区别,除非在内容中遇到了参数替换符$和
命令替换符`。
例如:
num=3
echo ‘$num’
$num
echo “$num”
3
所以,若在双引号””里面使用这两种符号,就要用反斜杠\进行转义。
2. 反引号``
与$()是一样的,均为命令替换符。
在执行一条命令时,会先将其中的``,或者是$()中的语句当作命令执行一遍,然后再将结果加入
到原命令中重新执行,例如:
echo `ls`
会先执行 ls 得到xx.sh等,再替换原命令为:
echo xx.sh
最后执行结果为
xx.sh
因此,平时我们遇到的把一堆命令的执行结果输出到一个变量中,需要用这个命令替换符括起来,
也就可以理解了。
这里又涉及到了一个问题,虽然不少系统工程师在使用替换功能时,喜欢使用反引号将命令括起来。
但是根据POSIX规范,要求系统工程师采用的是$(命令)的形式。所以,我们最好还是遵循这个规范,
少用``,多用$()。
3. 双括号(())
linux下shell中(())双括号运算符的使用详解:
在学习使用shell的逻辑运算符”[]”使用时候,必须保证运算符与算数之间有空格。
四则运算也只能借助let,expr等命令完成。 而双括号(())结构语句,就是对shell中算数及赋值运算的扩展。
使用方法:
语法:((表达式1,表达式2…))
特点:
1)在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。
2)在双括号结构中,所有变量可以不加入$符号前缀。
3)双括号可以进行逻辑运算,四则运算
4)双括号结构 扩展了for,while,if条件测试运算
5)支持多个表达式运算,各个表达式之间用逗号,分开
6)$(()),即双括号前带$,可将获得表达式值赋给左边变量
实例1(扩展四则运算)
#!/bin/sh
a=1
b=2
c=3
((a=a+1))
echo $a
a=$((a+1,b++,c++))
echo $a,$b,$c
运行结果:
sh testsh.sh
2
3,3,4
双括号结构之间支持多个表达式,然后加减乘除等c语言常用运算符都支持。
如果双括号前带$,将获得表达式值,赋值给左边变量。
实例2(扩展逻辑运算)
#!/bin/sh
a=1
b="ab"
echo $((a>1?8:9))
((b!="a"))&& echo "err2"
((a<2))&& echo "ok"
运行结果:
sh testsh.sh
9
err2
ok
实例3(扩展流程控制语句-逻辑关系式)
代码如下:
#!/bin/sh
num=100;
total=0;
for((i=0;i<=num;i++));
do
((total+=i));
done
echo $total;
total=0;
i=0;
while((i<=num));
do
((total+=i,i++));
done
echo $total;
if((total>=5050));then
echo "ok";
fi
运算结果:
sh testsh.sh
5050
5050
ok
有了双括号运算符后,[[]]、[]、test 逻辑运算、let、expr就不是必须的了。
4. $()和${}和$(())和(())
4.1 $()和${}的用法
$( )与` `反引号都是用来做命令替换用command substitution的。
${ } 其实就是用来作变量替换用。一般情况下,$var 与 ${var} 并没有区别。
但是用 ${ } 会比较精确的界定变量名称的范围。
举例:
var=123
echo $var #输出:123
echo $varabc #error
echo ${var}abc #输出:123abc
echo {$var}abc #输出:{123}abc
这里再用一些例子加以说明 ${ } 的一些特异功能:
假设我们定义了一个变量为:
file=/dir1/dir2/dir3/my.file.txt
我们可以用 ${ } 分别替换获得不同的值:
${file#*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt
${file#*.}:拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}:拿掉最后一个 . 及其左边的字符串:txt
${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}:拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
# 是去掉左边(在鉴盘上 # 在 $ 之左边)
% 是去掉右边(在鉴盘上 % 在 $ 之右边)
单一符号是最小匹配﹔两个符号是最大匹配。
${file:0:5}:提取最左边的 5 个字节:/dir1
${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2
我们也可以对变量值里的字符串作替换:
${file/dir/path}:将第一个 dir 提换为 path:/
path1/dir2/dir3/my.file.txt
${file//dir/path}:将全部 dir 提换为 path:/
path1/path2/path3/my.file.txt
利用 ${ } 还可针对不同的变量状态赋值(没设定、空值、非空值):
${file-my.file.txt} :假如 $file 没有设定,则使用 my.file.txt 作传回值。
(空值及非空值时不作处理)
${file:-my.file.txt} :假如 $file 没有设定或为空值,则使用my.file.txt
作传回值。 (非空值时不作处理)
${file+my.file.txt} :假如 $file 设为空值或非空值,均使用my.file.txt作
传回值。(没设定时不作处理)
${file:+my.file.txt} :若 $file 为非空值,则使用 my.file.txt 作传回值。
(没设定及空值时不作处理)
${file=my.file.txt} :若$file没设定,则使用 my.file.txt 作传回值,同时
将$file赋值为 my.file.txt 。(空值及非空值时不作处理)
${file:=my.file.txt} :若$file没设定或为空值,则使用my.file.txt作传回值,
同时将 $file 赋值为my.file.txt 。(非空值时不作处理)
${file?my.file.txt} :若 $file 没设定,则将 my.file.txt 输出至STDERR。
(空值及非空值时不作处理)
${file:?my.file.txt} :若 $file 没设定或为空值,则将 my.file.txt 输出至
STDERR。(非空值时不作处理)
以上的理解在于, 你一定要分清楚 unset 与 null 及 non-null 这三种赋值状态.
一般而言,:与null有关,若不带:的话,null 不受影响,若带:则连null 也受影响.
还有,${#var} 可计算出变量值的长度:
${#file} 可得到 27 ,因为 /dir1/dir2/dir3/my.file.txt 刚好是 27 个字节
4.2 $(())的用途
$(())是用来做整数运算的。
在 bash 中,$(( )) 的整数运算符号大致有这些:
+ - * / :分别为 "加、减、乘、除"。
% :余数运算
& | ^ !:分别为 "AND、OR、XOR、NOT" 运算。
举例:
wangnc>a=5;b=7;c=2;
wangnc>echo $a + $b
5 + 7
wangnc>echo $(( a + b*c))
19
wangnc>echo $(((a*b)/c))
17
wangnc>echo $(($a +$b*$c))
19
wangnc>
在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用,如:
$(( $a + $b * $c)) 也可得到 19 的结果
此外,$(( )) 还可作不同进位(如二进制、八进位、十六进制)作运算呢,只是,输出结果皆为十进制而已:
echo $((16#2a)) 结果为 42 (16进位转十进制)
4.3 (())的用途
事实上,单纯用 (( )) 也可重定义变量值,或作 testing:
a=5; ((a++)) 可将 $a 重定义为 6
a=5; ((a--)) 则为 a=4
a=5; b=7; ((a < b)) 会得到 0 (true) 的返回值
常见的用于 (( )) 的测试符号有如下这些:
< 小于
> 大于
<= 小于或等于
>= 大于或等于
== 等于
!= 不等于