l18.Linux通配符与特殊符号知识应用实践

1,546 阅读11分钟

“ 本文正在参加「金石计划 . 瓜分6万现金大奖」 ”

10.1 Linux通配符与特殊符号简介

Linux系统的功能非常强大且丰富,几乎键盘上的每个符号在Linux里都有很重要的作用和意义,今天笔者就和大家一起来梳理Linux学习里常见的通配符和特殊字符知识。

10.2 Linux通配符知识与实践

通配符简单地说就是,键盘上的一些特殊字符,可以实现某些特殊的功能,例如,用来模糊搜索系统中的文件。当查找文件时,可以使用通配符中的“*”或"?"字符来代替一个或多个真正的字符,从而更快地找到所需的文件。利用通配符可以在Linux命令行或bash脚本中轻松地匹配或查找所需的文件,以提高工作效率。

下面就为大家讲解一些常见的通配符知识与应用实践。通配符是bash的内置功能,几乎适用于所有的Linux命令。在企业工作中,常用的通配符符号如表10-1所示。

表10-1 通配符符号集合

b10-1.png

特别声明:后文在Linux三剑客命令对应的正则表达式功能中还会讲解上述符号的新功能,请读者分开记忆,不要弄混淆来。

10.2.1 通配符之“*”号的作用介绍与实践

在Linux命令行通配符中,"*"号的意思是匹配所有(0到多个)字符,这在查找某一类文件时特别方便,它在命令行中是十分常用的符号。下面来看几个相关的示例。

[root@centos7 ~]# mkdir test
[root@centos7 ~]# cd test/
[root@centos7 ~/test]# touch neteagle.txt hf.txt test.txt
[root@centos7 ~/test]# touch inca.sh
[root@centos7 ~/test]# ls
hf.txt  inca.sh  neteagle.txt  test.txt #3个txt结尾,1个sh结尾,共4个文件。

"*"号的使用示例如下。

1)查看所有结尾为txt的文件,示例代码如下:

[root@centos7 ~/test]# ls *.txt #结尾为".txt",开头匹配任意(0或多个)字符。
hf.txt  neteagle.txt  test.txt

2)查看所有结尾为sh的文件,“.sh”的前面可有任意个0。

[root@centos7 ~/test]# ls *.sh
inca.sh

10.2.2 通配符之“?”号的作用介绍与实践

在Linux命令行通配符中,"?"号代表的是任意一个字符(有且只有一个),这个字符在实际工作中运用得不多,读者了解即可。

"?"号的使用示例代码如下:

[root@centos7 ~/test]# ls
hf.txt  inca.sh  neteagle.txt  test.txt
[root@centos7 ~/test]# ls ?.sh  #问号仅匹配一个字符,因此,没有找到符合要求的文件。
ls: cannot access ?.sh: No such file or directory
[root@centos7 ~/test]# touch a.sh   #再创建一个文件。
[root@centos7 ~/test]# ls ?.sh  #重新匹配查找,这次找到了。
a.sh
[root@centos7 ~/test]# ls ????.sh   #列出4个????,匹配任意4个字符,就找到了inca.sh了。
inca.sh

10.2.3 通配符之[abcd]的作用介绍与实践

在Linux命令行通配符中,“[]”中括号这个符号里面可以加abcd等0到多个字符,表示匹配abcd中的任意一个字符(a、b、c、d中有且只有一个)。

[abcd]的使用示例代码如下:

[root@centos7 ~/test]# ls
a.sh  hf.txt  inca.sh  neteagle.txt  test.txt
[root@centos7 ~/test]# ls [abcd].sh #匹配".sh"结尾,且前面必须包含ab、c、d四个字符中的任意一个。
a.sh
[root@centos7 ~/test]# ls in[abc]a.sh   #匹配a.sh结尾,开头是in,之后是ab、c中的任意一个。
inca.sh

10.2.4 通配符之[a-z]的作用与实践

“[]”(中括号)这个符号里面的a-z,表示匹配a到z中的任意一个字符(有且只有一个),a-z要连续,也可以用连续的数字替代,例如,[1-9]表示的就是匹配1到9中的任意一个字符。

[a-z]号的使用示例代码如下:

[root@centos7 ~/test]# touch c.sh d.sh cd.sh
[root@centos7 ~/test]# ls
a.sh  cd.sh  c.sh  d.sh  hf.txt  inca.sh  neteagle.txt  test.txt
[root@centos7 ~/test]# ls [a-z].sh  #匹配“.sh”结尾,前面之包含a到z之间的任意一个字符。
a.sh  c.sh  d.sh
[root@centos7 ~/test]# ls [a-z]???.sh   #匹配a-z之间包含的任意一个字符开头,接下来是任意3个字符,然后以".sh"结尾,多个通配符可以组合使用。
inca.sh
[root@centos7 ~/test]# touch 1 2
[root@centos7 ~/test]# ls [1-9] #匹配09之间的任意一个数字。
1  2

10.2.5 通配符之[! abcd]的作用介绍与实践

[! abcd]表示匹配除了abcd四个字符以外的任意一个字符(有且只有一个),也可以写成[^abcd]或[^a-d],还可以用连续的数字替代,例如[^1-9]。

[! abcd]的使用示例代码如下:

[root@centos7 ~/test]# touch a b c d e f 
[root@centos7 ~/test]# ls [^abcd]   #匹配包含ab、c、d任意字符以外的单个字符。
1  2  e  f
[root@centos7 ~/test]# ls
1  a     b  cd.sh  d     e  hf.txt   neteagle.txt
2  a.sh  c  c.sh   d.sh  f  inca.sh  test.txt
[root@centos7 ~/test]# ls [!abcd]   #匹配包含ab、c、d任意字符以外的单个字符。
1  2  e  f
[root@centos7 ~/test]# ls [!a-d]    #匹配包含ab、c、d任意字符以外的单个字符。
1  2  e  f
[root@centos7 ~/test]# ls [!1-9]    #匹配包含19任意数字以外的单个字符。
a  b  c  d  e  f

10.2.6 通配符之综合实践案例

范例10-1: 查找/etc目录下包含hosts字符串的所有文件。

[root@centos7 ~/test]# find /etc/ -type f -name "*hosts*"
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny

范例10-2: 查找/etc目录下的所有文件,规则是文件名的第一个字符为任意字符,第二个字符为0、p、q中的任意一个字符,第三个字符不能在a到r之间,结尾是ts。

[root@centos7 ~/test]# find /etc/ -type f -name "?[opq][^a-r]ts"
/etc/hosts

提示:这道题没有什么实际用途,纯粹是为了练习通配符组合。

10.3 Linux特殊符号知识与实践

相比通配符来说,Linux特殊符号更加复杂,且杂乱无章,但是,要想成为一个合格的Linux运维工程师,就必须要掌握这些特殊符号。

10.3.1 与路径和位置有关的特殊符号

为了便于读者掌握特殊符号知识,笔者将相应符号做了一个归类,在Linux中,与路径和位置有关的特殊符号见表10-2。后面会根据归类进一步讲解具体含义,并进行实际。

表10-2 通配符符号集合

b10-2.png

10.3.1.1 波浪线(~)的介绍与实践

在Linux系统命令行中,“~”代表用户的家目录,超级用户为“/root”,普通用户为"/home"。

示例代码如下:

[root@centos7 ~/test]# pwd
/root/test  #当前路径。
[root@centos7 ~]# cd ~  #切换到用户家目录,即/root。
[root@centos7 ~]# pwd
/root   # root用户家目录。

10.3.1.2 短横杠(-)的介绍与实践

在Linux系统命令行中,“-”代表上一次用户所在的路径。

示例代码如下:

[root@centos7 ~]# cd test
[root@centos7 ~/test]# cd -
/root
[root@centos7 ~]# pwd
/root
[root@centos7 ~]# echo $OLDPWD  #查看上一次所在路径的变量命令。
/root/test  #上一次所在路径。
[root@centos7 ~]# cd -  #切换到上一次所在路径,即/root/test。
/root/test
[root@centos7 ~/test]# echo $OLDPWD #再查看上一次所在路径。
/root
[root@centos7 ~/test]# cd - #切到上一次所在路径,即/root。
/root

10.3.1.3 点号(.)的介绍与实践

在Linux系统命令行中,点号代表当前目录,示例代码如下:

[root@centos7 ~]# cd test
[root@centos7 ~/test]# pwd  #查看当前路径。
/root/test
[root@centos7 ~/test]# cd . #切换到点号所在路径。
[root@centos7 ~/test]# pwd
/root/test  #还是在原来的路径下。
[root@centos7 ~/test]# find . -name "*.sh"  #查找当前路径下的所有符合“*.sh”的文件。
./inca.sh
./a.sh
./c.sh
./d.sh
./cd.sh

提示: 这里的点号代表/root/test,即当前命令所在的路径。

10.3.1.4 双点号(..)的介绍与实践

在Linux系统命令行中,双点号代表当前目录的上一级目录,示例代码如下:

[root@centos7 ~/test]# pwd  #查看当前路径。
/root/test
[root@centos7 ~/test]# cd ..    #切换到双点号所在路径。
[root@centos7 ~]# pwd
/root   #路径变到了“/root”下,原来是/root/test,上级正好是/root。
[root@centos7 ~]# mkdir dir1
[root@centos7 ~]# ls -a dir1/
.  ..   #任何一个新目录下都有一个点号(当前目录)和一个双点号(上级目录)。

10.3.2 不同引号特殊符号的知识与实践(重要)

在Linux命令行或脚本中,处理字符串时,经常会涉及引号问题,很多新手在操作命令时,不知道该不该加引号,或者应该加什么样的引号,什么时候可以不加。为此笔者在此列出了一个表格与读者分享(见表10-3),后文再进行实践演练,表10-3来源于《跟老男孩学Linux运维:Shell编程实战》的3.3.1节。

表10-3 单引号、双引号与不加引号、反引号的知识说明

b10-3.png

10.3.2.1 反引号(``)的介绍与实践

简单来说,当将待处理的字符串用反引号引起来的时候,系统首先会将反引号里字符串当作命令进行解析,然后针对解析后的结果做进一步的处理。反引号一般用于引用命令,执行的时候命令会被执行,相当于“$ ()”,赋值和输出都要将命令用反引号(``)引起来。下面以echo命令为例来检验上述描述结果:

[root@centos7 ~]# date  #打印系统当前日期的命令。
Tue Oct 13 17:10:52 CST 2020
[root@centos7 ~]# echo date #若不加反引号,就会将date当作字符串输出。
date
[root@centos7 ~]# echo `date`   #将date命令反引起来,系统会将date当作是一个命令。
Tue Oct 13 17:11:13 CST 2020
[root@centos7 ~]# echo `aa` #aa被反引起来之后,将作为命令解析。
-bash: aa: command not found    #aa命令找不到,从提示信息可以得知,系统将aa当作命令执行了。
​
[root@centos7 ~]# cd test/
[root@centos7 ~/test]# touch `date +%F.txt` #将命令反引起来作为待创建的文件名。
[root@centos7 ~/test]# ls `date +%F.txt`    #查看,date命令见后文。
2020-10-13.txt
[root@centos7 ~/test]# ll `which cat`   #将查看命令反引起来作为ls的待处理文件。
-rwxr-xr-x. 1 root root 54080 Aug 20  2019 /usr/bin/cat

10.3.2.2 双引号("")的介绍与实践

当输出双引号内的所有内容是,如果内容中有命令(要反引一些)、变量、特殊转义符等,则会先将变量、命令、转义字符解析出来,然后输出最终的内容。若在平时引用字符串时,不知道应该如何引用,则可以默认使用双引号,这种引用也成为弱引用。示例代码如下:

[root@centos7 ~/test]# echo "date"  #被引用的内容作为字符串输出。
date
[root@centos7 ~/test]# echo "`date`"    #经过反引号引起来的命令会在解析后输出。
Tue Oct 13 17:19:09 CST 2020
[root@centos7 ~/test]# echo "$(date) `which mkdir`" #经过反引号或"$()"引起来的命令会在解析后输出。
Tue Oct 13 17:19:38 CST 2020 /usr/bin/mkdir
[root@centos7 ~/test]# echo "today is `date +%w`"
today is 2

10.3.2.3 单引号('')的介绍与实践

简单来说,当将待处理的内容用单引号引起来时,引号里面有什么内容,处理时就一直保持引号之前的内容不变,下面用echo命令来检验上述描述的结果:

[root@centos7 ~/test]# echo 'date'  #即使是命令也会作为字符串原样输出。
date
[root@centos7 ~/test]# echo '`date`'    #用反引号引起来也没用,还是原样输出。
`date`

结论: 当用echo输出时,用单引号引起的内容是什么,输出来的内容就是什么,不会有任何改变(就是“所见即所得”)。

10.3.2.4 无任何引号的介绍与实践

不适用引号的功能与双引号类似,但由于没有引号,很难确定字符串的边界,因此很容易出现各种未知的操作错误,综上所述,若无特殊情况,在处理字符串内容时建议读者使用双引号替代不加引号(连续的数字字符串可以不加引号)的情况。示例代码如下:

[root@centos7 ~/test]# echo "today is `date +%w`"
today is 2
[root@centos7 ~/test]# echo today is `date +%w`
today is 2
[root@centos7 ~/test]# echo I am neteagle
I am neteagle
[root@centos7 ~/test]# echo $(date) `which mkdir`
Tue Oct 13 17:29:50 CST 2020 /usr/bin/mkdir

10.3.3 重定向特殊符号知识与实践(重要)

这部分内容在前面章节中已经详细讲解过,这里仅给出相关表格(见表10-4),供读者复习参考。

表10-4 重定向相关知识总结表格

b10-4.png

10.3.4 其他特殊符号知识与实践(重要)

其他特殊符号相关知识总结如表10-5所示。

表10-5 其他特殊符号相关知识总结

b10-5.png

10.3.4.1 分号(;)的介绍与实践

在Linux命令行中,分号(;)表示一个命令的结束,它是命令间的分隔符。在有些配置文件中,以分号开头的内容代表注释,例如在keeplived.conf高可用配置中就是如此。

“;”号的使用示例代码如下:

[root@centos7 ~/test]# pwd; #结尾加了分号。
/root/test
[root@centos7 ~/test]# pwd;pwd  #分割两个命令。
/root/test
/root/test
/root/test
[root@centos7 ~/test]# pwd;ls
/root/test
1               a     c      d     f        neteagle.txt
2               a.sh  cd.sh  d.sh  hf.txt   test.txt
2020-10-13.txt  b     c.sh   e     inca.sh

10.3.4.2 #号(#)的介绍与实践

在Linux系统的配置文件中,经常会看到以“#”号开头的内容,表示后面的是注释内容,这部分内容是给管理员看的,系统不会执行以“#”开头的内容。示例代码如下:

[root@centos7 ~/test]# tail /etc/ssh/sshd_config# override default of no subsystems
Subsystem   sftp    /usr/libexec/openssh/sftp-server
​
# Example of overriding settings on a per-user basis
#Match User anoncvs
#   X11Forwarding no
#   AllowTcpForwarding no
#   PermitTTY no
#   ForceCommand cvs server

10.3.4.3 管道符(|)的介绍与实践

在Linux系统命令行中,管道符(|)是极其重要的符号,是命令行中十分常见的符号。

提到管道二字,大家能想起什么来?是否会想起生活中的下水道、自来水管道等呢?图10-1所示的就是一处工地施工铺设的管道。

t10-1.png

图10-1 工地施工铺设的管道

Linux中管道的作用与图10-1所示的管道作用是类似的,只不过Linux管道里传输的是数据流,而不是水流或气流,在实际命令行中,一个命令处理后并未得到想要的结果为止,此时需要将数据交给其他命令继续处理,知道得到最终结果为止,在命令和命令之间就需要用管道衔接将数据流发过来进行处理。

管道符(|)的使用示例代码如下:

[root@centos7 ~/test]# ifconfig |grep 10.0.0    #将ifconfig的输出结果输出给grep进行过滤。
        inet 10.0.0.201  netmask 255.255.255.0  broadcast 10.0.0.255
[root@centos7 ~/test]# cat /etc/services |grep 3306 #读取服务文件输出给grep过滤。
mysql           3306/tcp                        # MySQL
mysql           3306/udp                        # MySQL

提示:

  • 对于文件的过滤,尽量不要使用管道,而是直接用grep 3306 /etc/services这样的命令。
  • 管道虽然方便,但是效率并不高,因此,执行命令时能尽量一次出结果,就不要使用管道。

10.3.4.4 美元符($)的介绍与实践

在Linux系统命令行或Shell脚本程序中,在字符串前加"$"符号,代表的是字符串变量的内容。示例代码如下:

[root@centos7 ~/test]# echo $OLDPWD
/root
[root@centos7 ~/test]# echo $PS1
[[\e[34;1m]\u@[\e[0m][\e[32;1m]\H[\e[0m][\e[31;1m] \w[\e[0m]]$
[root@centos7 ~/test]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos7 ~/test]# neteagle=1
[root@centos7 ~/test]# echo $neteagle
1

10.3.4.5 大括号({})的介绍与实践

"{}"有多种用途,下面分别来看看。

1)“{}”表示生成序列(一连串的文本),示例代码如下:

[root@centos7 ~/test]# echo {1..10} #两个点号表示从110,默认以空格分隔。
1 2 3 4 5 6 7 8 9 10
[root@centos7 ~/test]# echo {a..g}  #两个点号表示从a到g的所有字符,默认以空格分隔。
a b c d e f g
[root@centos7 ~/test]# echo {n,e,t,e,a,g,l,e}   #用逗号分开,列出来。
n e t e a g l e

2)利用“{}”功能来快速备份关键文件(特殊应用),示例代码如下:

[root@centos7 ~/test]# cp /etc/ssh/sshd_config{,.ori}
#等价/etc/ssh/sshd_config /etc/ssh/sshd_config.ori。
cp: overwrite ‘/etc/ssh/sshd_config.ori’? 
[root@centos7 ~/test]# ll /etc/ssh/sshd_config{,.ori}
-rw-------. 1 root root 3907 Aug  9  2019 /etc/ssh/sshd_config
-rw-------. 1 root root 3907 Oct  6 18:26 /etc/ssh/sshd_config.ori

3)将变量括起来作为变量的分隔符,示例代码如下:

[root@centos7 ~/test]# week=6   #定义变量week并赋值6.
[root@centos7 ~/test]# echo $week   #输出变量值。
6
[root@centos7 ~/test]# echo "$week_neteagle"    #输出为空,系统将week_neteagle作为变量了。
​
[root@centos7 ~/test]# echo "${week}_neteagle"  #将week用大括号括起来再输出就对了。
6_neteagle

10.3.5 Bash中的逻辑操作符系列

本节的内容既可以在Bash脚本中使用,也可以在Linux命令行中使用。Bash中的逻辑操作符系列的相关总结见表10-6.

表10-6 Bash中逻辑操作符系列

b10-6.png

10.4 Linux通配符与特殊符号知识小结

Linux的通配符与特殊符号的知识比较繁杂,不好记忆,读者要通过不断地练习和总结来加强记忆,在本章结尾,笔者将本章讲解的内容以表格(表10-7)的形式整理如下。

表10-7 Linux通配符与特殊符号知识总结

b10-7-1.png

b10-7-2.png