SHELL 进阶
这部分的知识,我们主要是从三个方面来学习:
测试语句
表达式(条件+计算)
linux常见符号和命令
3.1 表达式
要使Shell脚本程序具备一定的“逻辑能力”,面临的第一个问题就是:区分不同的情况以确定执行何种操作,下面 我们就来学习解决这个问题---测试语句
3.1.1 测试语句
shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0,表示成功,值为其他时,表示失败 。使用专门的测试工具---test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值0为成立)
测试语句形式
A:test 条件表达式
b:[ 条件表达式 ]
格式注意:
以上两种方法的作用完全一样,后者较为常用。
但后者需要注意方括号[、]与条件表达式之间至少有一个空格。
test和[] 的意思一样
条件成立,状态返回值是0
条件不成立,状态范回值是1
操作注意
- []两侧为什么要有空格
tarena@tarena:~$ [-x /bin/bash] [-x: cammand not found
可以看到:
两侧没有空格,就会报错,为什么呢?因为你不合规范。
3.1.2 条件表达式
我们这部分内容主要是介绍,测试语句中的 [ 条件表达式 ] 这一部分,测试的结果使用 echo $? 来查看
逻辑表达式
逻辑表达式一般用于判断多个条件之间的依赖关系。
常见的逻辑表达式有: && 和 ||
&&
命令1 && 命令2
如果命令1执行成功,那么我就执行命令2 -- 夫唱妇随
如果命令1执行失败,那么命令2也不执行
示例:
# [ 1 = 1 ] && echo "条件城里" 条件成立 # [ 1 = 2 ] && echo "条件成立" #
||
命令1 || 命令2
如果命令1执行成功,那么命令2不执行 -- 对着干
如果命令1执行失败,那么命令2执行
示例:
# [ 1 = 2 ] || echo "条件不成立" 条件不成立 # [ 1 = 1 ] || echo "条件不成立" #
文件表达式
-f
判断输入内容是否是一个文件
- 示例:
# [ -f weizhi.sh ] && echo "是一个文件" 是一个文件 # [ -f weizhi.sddh ] || echo "不是一个文件" 不是一个文件
-d
判断输入内容是否是一个目录
- 示例:
# [ -d weizhi.sddh ] || echo "不是一个目录" 不是一个目录 # mkdir nihao # [ -d nihao ] && echo "是一个目录" 是一个目录
-x
判断输入内容是否可执行
- 示例:
# [ -x age.sh ] || echo "文件没有执行权限" 文件没有执行权限 # [ -x test.sh ] && echo "文件有执行权限" 文件有执行权限
数值操作符
主要根据给定的两个值,判断第一个与第二个数的关系,如是否大于、小于、等于第二个数。常见选项如下:
n1 -eq n2 相等 n1 -gt n2 大于 n1 -lt n2 小于 n1 -ne n2 不等于
字符串比较
str1 == str2 str1和str2字符串内容一致 str1 != str2 str1和str2字符串内容不一致,!表示相反的意思 示例:
- 判断字符串内容是否一致
root@ubuntu:~# [ a == a ] root@ubuntu:~# echo $? 0 root@ubuntu:~# [ a != a ] root@ubuntu:~# echo $? 1
3.1.3 计算表达式
定义:
计算表达式,简单来说就是对具体的内容进行算数计算
格式:
- 方式一:
$(()) $(( 计算表达式 ))
- 方式二:
let let 计算表达式
注意:
$(())中只能用+-*/和()运算符,并且只能做整数运算
$(()) 演示效果
格式:a=$((变量名a+1))
注意:
表达式范围内,空格不限制
计算示例:
tarena@tarena:~$ echo $((100/5)) 20
let 效果演示
格式:let 变量名a=变量名a+1
注意:
表达式必须是一个整体,中间不能出现空格等特殊字符
let示例:
tarena@tarena:~$ i=1 tarena@tarena:~$ let i=i+7 tarena@tarena:~$ echo $i 8
3.2 linux 常见符号
接下来我们来介绍几个linux的场景符号:
- 重定向符号
- 管道符
- 其他符号
3.2.1 重定向符号
在shell脚本中有两种常见的重定向符号 > 和 >>
> 符号
作用:
> 表示将符号左侧的内容,以覆盖的方式输入到右侧文件中
演示:
向文件中添加东西:
'nihao' > file.txt
查看文件内容:
tarena@tarena:~$ cat file.txt nihao
使用重定向符号给文件中增加内容:
tarena@tarena:~$ echo "file1.txt" > file.txt
再次查看文件内容:
tarena@tarena:~$ cat file.txt file1.txt
>> 符号
作用:
>> 表示将符号左侧的内容,以追加的方式输入到右侧文件的末尾行中
演示:
查看文件内容
tarena@tarena:~$ cat file.txt file1.txt
使用重定向符号给文件中增加内容
tarena@tarena:~$ echo "file2.txt" >> file.txt
再次查看文件内容
tarena@tarena:~$ cat file.txt file1.txt file2.txt
3.2.2 管道符 |
定义:
`| ` 这个就是管道符,传递信息使用的
使用格式:
命令1 | 命令2 管道符左侧命令1 执行后的结果,传递给管道符右侧的命令2使用
命令演示:
查看当前系统中的全局变量SHELL
tarena@tarena:~$ env | grep SHELL SHELL=/bin/bash
3.3 常见命令详解
接下来我们介绍一些shell脚本中经常使用的linux命令:grep、sed、awk、find
3.3.1 grep 命令详解
grep命令是我们常用的一个强大的文本搜索命令。
命令格式详解
grep [参数] [关键字] <文件名>
注意:
- 我们在查看某个文件的内容的时候,是需要有<文件名>
- grep命令在结合|(管道符)使用的情况下,后面的<文件名>是没有的
- 可以通过 grep --help 查看grep的帮助信息
参数详解:
-c: 只输出匹配行的计数。 -n: 显示匹配行及行号。 -v: 显示不包含匹配文本的所有行。 模板文件
tarena@tarena:~$ cat find.txt nihao aaa nihao AAA NiHao bbb nihao CCC
-c:
输出匹配到aaa的个数tarena@tarena:~$ grep -c aaa find.txt 1
-n:
输出匹配内容,同时显示行号tarena@tarena:~$ grep -n CCC find.txt 4:nihao CCC
-v: 匹配到的内容部输出,输出不匹配的内容
tarena@tarena:~$ grep -v ni find.txt NiHao bbb
小技巧:
- 精确定位错误代码 grep -nr [错误关键字] *
3.3.2 sed 命令详解
sed 行文件编辑工具。因为它编辑文件是以行为单位的。
命令格式详解
命令格式:
sed [参数] '<匹配条件> [动作]' [文件名]
注意:
可以通过 sed --help 查看grep的帮助信息
参数详解:
参数为空 表示sed的操作效果,实际上不对文件进行编辑
-i 表示对文件进行编辑
注意: mac版本的bash中使用 -i参数,必须在后面单独加个东西: -i ''
匹配条件:
匹配条件分为两种:数字行号或者关键字匹配
关键字匹配格式
'/关键字/' **注意:** 1. 隔离符号 / 可以更换成 @、#、! 等符号 2. 根据情况使用,如果关键字和隔离符号有冲突,就更换成其他的符号即可
动作详解:
-a 在匹配到的内容下一行增加内容 -i 在匹配到的内容上一行增加内容 -d 删除匹配到的内容 -s 替换匹配到的内容 注意:
上面的动作应该在参数为-i的时候使用,不然的话不会有效果
替换命令演示
关于替换,我们从三个方面来学习:
行号、列号、全体
命令格式:
sed -i [替换格式] [文件名]
注意:
- 替换命令的写法 's###' ---> 's#原内容##' ---> 's#原内容#替换后内容#'
样式一:
sed -i '行号s#原内容#替换后内容#列号' [文件名]
样式二:
sed -i 's#原内容#替换后内容#g' [文件名]
常见替换格式:
模板文件内容
tarena@tarena:~$ cat sed.txt nihao sed sed sed nihao sed sed sed nihao sed sed sed
替换每行首个匹配内容:
sed -i 's#原内容#替换后内容#' 文件名
示例:替换首每行的第1个sed为SED
tarena@tarena:~$ sed -i 's#sed#SED#' sed.txt tarena@tarena:~$ cat sed.txt nihao SED sed sed nihao SED sed sed nihao SED sed sed
替换全部匹配内容:
sed -i 's#原内容#替换后内容#g' 文件名
示例:替换全部sed为des
tarena@tarena:~$ sed -i 's#sed#SED#g' sed.txt tarena@tarena:~$ cat sed.txt nihao SED SED SED nihao SED SED SED nihao SED SED SED
指定行号替换首个匹配内容:
sed -i '行号s#原内容#替换后内容#' 文件名
示例:替换第2行的首个SED为sed>
tarena@tarena:~$ sed -i '2s#SED#sed#' sed.txt tarena@tarena:~$ cat sed.txt nihao SED SED SED nihao sed SED SED nihao SED SED SED
首行指定列号替换匹配内容:
sed -i 's#原内容#替换后内容#列号' 文件名
示例:替换每行的第2个SED为sed
tarena@tarena:~$ sed -i 's#SED#sed#2' sed.txt tarena@tarena:~$ cat sed.txt nihao SED sed SED nihao sed SED sed nihao SED sed SED
指定行号列号匹配内容:
sed -i '行号s#原内容#替换后内容#列号' 文件名
示例:替换第3行的第2个SED为sed
tarena@tarena:~$ sed -i '3s#SED#sed#2' sed.txt tarena@tarena:~$ cat sed.txt nihao SED sed SED nihao sed SED sed nihao SED sed sed
增加操作
作用:在指定行号的下一行增加内容
格式:sed -i '行号a\增加的内容' 文件名
注意:
- 如果增加多行,可以在行号位置写个范围值,彼此间使用逗号隔开,例如 sed -i '1,3a\增加内容' 文件名 演示效果:
指定行号增加内容
tarena@tarena:~$ sed -i '2a\zengjia-2' sed.txt tarena@tarena:~$ cat sed.txt nihao SED sed SED nihao sed SED sed zengjia-2 nihao SED sed sed
指定1~3每行都增加内容
tarena@tarena:~$ sed -i '1,3a\tongshi-2' sed.txt tarena@tarena:~$ cat sed.txt nihao SED sed SED tongshi-2 nihao sed SED sed tongshi-2 zengjia-2 tongshi-2 nihao SED sed sed
作用:在指定行号的当行增加内容
格式:sed -i '行号i\增加的内容' 文件名
注意:
- 如果增加多行,可以在行号位置写个范围值,彼此间使用逗号隔开,例如 sed -i '1,3i\增加内容' 文件名
演示效果:
指定行数增加内容
tarena@tarena:~$ sed -i '1i\insert-1' sed.txt tarena@tarena:~$ cat sed.txt insert-1 nihao SED sed SED tongshi-2 nihao sed SED sed tongshi-2 zengjia-2 tongshi-2 nihao SED sed sed
删除操作
作用:指定行号删除
格式:sed -i '行号d' 文件名
注意:
- 如果删除多行,可以在行号位置多写几个行号,彼此间使用逗号隔开,例如 sed -i '1,3d' 文件名
删除演练
- 删除第四行内容
tarena@tarena:~$ sed -i '4d' sed.txt tarena@tarena:~$ cat sed.txt insert-1 nihao SED sed SED tongshi-2 tongshi-2 zengjia-2 tongshi-2 nihao SED sed sed
3.3.3 awk命令详解
awk是一个功能非常强大的文档编辑工具,它不仅能以行为单位还能以列为单位处理文件。
命令格式
awk [参数] '[ 动作]' [文件名]
常见参数:
-F 指定行的分隔符
常见动作:
显示内容 $0 显示当前行所有内容 $n 显示当前行的第n列内容,如果存在多个$n,它们之间使用逗号(,)隔开
常见内置变量
FILENAME 当前输入文件的文件名,该变量是只读的 NR 指定显示行的行号 NF 输出 最后一列的内容 OFS 输出格式的列分隔符,缺省是空格 FS 输入文件的列分融符,缺省是连续的空格和Tab
命令演示
模板文件内容
tarena@tarena:~$ cat awk.txt nihao awk awk awk nihao awk awk awk
打印指定列内容
打印第1列的内容tarena@tarena:~$ awk '{print $1}' awk.txt nihao nihao
指定行打印内容
打印第一行第1和第3列内容tarena@tarena:~$ awk 'NR==1 {print $1,$3}' awk.txt nihao awk
指定隔离分隔符,查看内容
tarena@tarena:~$ cat linshi.txt root:x:0:0:root:/root:/bin/bash tarena@tarena:~$ awk -F ':' '{print $1,$7}' linshi.txt root /bin/bash
设置显示分隔符,显示内容
tarena@tarena:~$ awk 'BEGIN{OFS=":"} {print NR,$0}' awk.txt 1:nihao awk awk awk 2:nihao awk awk awk
3.3.4 find命令详解
命令格式
find [路径] [参数] [关键字]
参数详解
-name 按照文件名查找文件。 -perm 按照文件权限来查找文件。 -user 按照文件属主来查找文件。 -group 按照文件所属的组来查找文件。 -type 查找某一类型的文件 诸如:b - 块设备文件 d - 目录 c - 字符设备文件 p - 管道文件 l - 符号链接文件 f - 普通文件 -size n [c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。 -depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。 -mindepth n 在查找文件时,查找当前目录中的第n层目录的文件,然后再在其子目录中查找。 ! 表示取反
命令演示
在当前系统中查找一个叫awk的文件
tarena@tarena:~$ sudo find /home/admin-1/ -name "awk.txt" /home/tarena/awk.txt
在当前系统中查找文件类型为普通文件的文件
tarena@tarena:~$ find /tmp -type f /tmp/.X0-lock /tmp/vgauthsvclog.txt.0 /tmp/unity_support_test.0 /tmp/config-err-4igbXW