「 SHELL 」进阶

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 指定行的分隔符

常见动作:

print 显示内容
$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

你可能感兴趣的:(「 SHELL 」进阶)