理解下 shell 脚本中的文件名匹配和命令执行的顺序与结果。我们学习这个的目的是可以熟悉的在 shell 脚本中写出快速的找到文件的命令。它可以匹配文件名中的任何字符串,匹配文件名中的单个字符以及匹配文件名中的字母或数字符号。

首先我们来看看匹配文件的符号的定义,匹配字符串类型的符号称之为元字符。匹配文件名中的任意字符串,同时也包括空字符串。

举例:ls /etc/*.conf ls /etc/h*.co*f。结果如下

shell grep 模糊搜索 shell脚本模糊匹配文件名_文件名

我们看到成功的匹配到了 /etc 目录下的 h 开头的 con*f 结尾的所有文件,那么我们以后在文件的查找中就很方便了。

下来我们来看看?匹配文件,那么它是能匹配文件名中的任何单个字符。

举例:ls /etc/hos?.conf ls /etc/??g.conf。结果如下所示

shell grep 模糊搜索 shell脚本模糊匹配文件名_字符串_02

下来继续来看看 [ ] 匹配文件,[ ... ] 匹配 [ ] 中所包含的任意一个字符。有两种匹配方式:a> 杂乱匹配:ls /etc/[wsdcr]syslog.conf;b> 范围匹配:ls [0-9][a-zA-Z].txt

shell grep 模糊搜索 shell脚本模糊匹配文件名_文件名_03

我们看到已经匹配出来了。[ !... ] 匹配 [ ] 中非感叹号!之后的任意一个字符,它与上一条规则刚好相反。举例:ls [!0-9]*.txt。此条是匹配非数字开头的后缀名为 txt 的所有文件。如下

shell grep 模糊搜索 shell脚本模糊匹配文件名_文件名_04

下来我们来看看一个综合应用:查找一个以数字开头,接着包括两个小写英文字母,然后再接任意两个字符的以 .conf 结尾的文件名。(如:5abcui.conf 是符合条件的)

#! /bin/bash

ls [0-9][a-z][a-z]???.conf

我们来看看结果

shell grep 模糊搜索 shell脚本模糊匹配文件名_文件名_05

我们在平时的输出 log 中通常会以特定字符+年月日来进行保存,那么我们的创建 log 的方式就如下

shell grep 模糊搜索 shell脚本模糊匹配文件名_bc_06

如果我们能熟练的使用匹配字符,那么便可以大大减少在查找文件名上的工作量,这是一种非常有效的模式匹配方法。

下来我们接着看看命令执行的顺序和结果。我们知道在一般的命令中,它是有返回执行结果的,成功则返回 1,失败返回 0;同样的,在Linux中,也是有命令的返回结果的,只不过是它比较特殊,成功时返回 0,失败时返回非 0。下来我们看看示例,如下

shell grep 模糊搜索 shell脚本模糊匹配文件名_文件名_07

我们看到在 ls abcs.log 时,由于没有这个文件,因此它的返回值为 2(非 0);在 ls 2.txt 时,这个文件是存在的,因此它的返回值为 0。

下来我们来看看命令的执行控制:a> 使用 && 符号;b> 使用 || 符号;c> 命令的组合使用“;”。

a> 使用 && 符号

格式:命令 1 && 命令 2 && ··· ;说明:如果命令 1 执行成功,那么执行命令 2 ···

举例:cp /etc/sysctl.conf /mnt/ && echo "Copy file success"

shell grep 模糊搜索 shell脚本模糊匹配文件名_shell grep 模糊搜索_08

我们看到在有文件存在的情况下,便执行后面的 echo 命令,打印出了 Copy file success。在前面的命令没有执行成功的情况下,没有继续执行后面的 echo 命令。我们在编译源码时:./configure && make && make install ,它的用处是用于脚本的执行的调试。

b> 使用 || 符号

格式:命令 1 || 命令 2 || ···;说明:如果 || 左边的命令执行失败了,那么接着执行右边的命令。

举例:cp hello.txt copy.txt || echo "Copy file failed"

shell grep 模糊搜索 shell脚本模糊匹配文件名_文件名_09

它的用处也是用于支持脚本的执行的调试。

c> 命令的组合使用

格式 1:“;”一次下达两个以上的命令

格式 2:( 命令 1;命令 2;... ) 在当前 shell 中执行

格式 3:{ 命令 1;命令 2;... } 在子 shell 中执行

举例:

1、ls /usr/;cd;echo "OK"

2、(ls; cat a.txt; cd) || echo "success"

我们看到在 || 后,执行前面的命令后,如果执行成功则后面的命令不会执行。