shell 正则qia 波浪线_linux操作:Shell操作|echo|扩展

eb4a327fb20748c26050704b5fae673d.png

在本章,我们将介绍在按下Enter键时,命令行中发生的一些“神奇”事情。虽然我们会介绍shell的几个有趣而复杂的特性,但是我们只使用一条新命令来处理。

  • echo:显示一行文本。
  • *
  • ~
  • $
  • ""
  • ''

1.扩展

每次输入命令行按下Enter键时,bash都会在执行命令之前对文本进行多重处理。前面已经见过一个简单的字符序列(比如*)在shell中被识别为多种意思的几个例子。产生这个结果的处理过程称为扩展(expansion)。有了扩展功能,在输入内容后,这些内容将在shell对其执行之前被扩展成其他内容。为了证明这点,让我们先来看看echo命令。echo是shell的一个内置命令,它执行的任务非常简单,即把文本参数内容打印到标准输出。

b325fe7fcefbc981765466d5e70c3e67.png

cdb60946a483c56dffc6968739231234.png
“*”字符意味着“匹配文件名中的任意字符”,但是之前我们并没有讨论shell是如何实现这个功能的。答案很简单,shell会在执行echo命令前把“*”字符扩展成其他内容(在这个例子中,扩展为当前工作目录下的所有文件名)。
  • 路径名扩展

通过使用通配符来实现扩展的机制称为路径名扩展(pathname expansion)。试试在前面通过使用通配符来实现扩展的机制称为路径名扩展(pathname expansion)。试试在前面章节中使用过的一些技术,将会发现它们实际上就是扩展。下面给定一个主目录,如下所示:

299f3e01119a7e3b57c38db2fadad396.png

执行下面的扩展:

af6e7551f99f848bc889714c02f7d803.png

e5e567aea55f44603c2bd3fe4f027d6e.png

64b6abb2dedba8460f25f5d00c47ea11.png

f0d4a5c5a14aa32b1e5ab907f663c924.png
查看除主目录之外的目录:

bbe05bb41dda513f354998dcc8f41a24.png

2c0f084034bfdfa18d65a82bdf646fa6.png
间隔星星个数

隐藏文件的路径名扩展

众所周知,文件名以一个“.”点字符开头的文件都将被隐藏。路径名扩展功能也遵守这个规则。类似echo *这样的扩展并不能显示隐藏的文件。

乍一看,好像可以通过在扩展的模式中以一个点字符开头来包含隐藏文件,如下所示。

echo .*

b8a8b1a7fd9eff30fa40dde5085c5f57.png

6f12e72cc97959269faae77375d7f09b.png
这似乎是可行的。但是如果我们仔细地检查结果,会发现文件名“.”和“..”也将出现在结果中。由于这两个名字分别指的是当前的工作目录以及当前目录的父目录,使用这种模式匹配可能会生成不正确的结果。

。执行命令行ls –d .*|less可以发现这个结果是不正确的。

4b0c67d206c5269c01116d57d0c994c6.png

ls -d .[!.]?*

这种模式将扩展为以一个点字符开头的所有文件名,文件名中并不包含第二个点字符,但包含至少一个额外的字符,后面也可能还跟着其他的字符。

9a1d4184f8a5b11acc5740e2c08b248b.png

波浪线扩展

回顾前面对cd命令的介绍,你会发现波浪线字符(~)具有特殊的含义。如果把它用在一个单词的开头,那么它将被扩展为指定用户的主目录名;如果没有指定用户命名,则扩展为当前用户的主目录。

2e7dc31a62c7896b2d38c7345a96f138.png

算术扩展

shell支持通过扩展来运行算术表达式。这允许我们把shell提示符当作计算器来使用。

944f34564f83ff63c685993a22446e28.png

算术扩展只支持整数(全是数字,没有小数),但是可以执行很多不同的运算。表1列出了一些支持的操作符。

392211e3ff02a4d624ad2b405a5e5329.png

0d837cebfbfbfa3b4b644afc0fc015a3.png

空格在算术表达式中是没有意义的,而且表达式是可以嵌套的。例如把 52和3相乘。

c40dd28c38d75615163961b72d0c49fe.png
嵌套成对括号

下面的例子使用了除运算符和取余运算符,注意整数相除的结果。

ba5912cf3e4116da15f3d088e2f647fa.png

花括号扩展

花括号扩展(brace expansion)可能算是最奇怪的扩展方式了。有了它,你可以按照花括号里面的模式创建多种文本字符串。实例如下。

f11d289b3051e108cc08a4db2c0fb588.png

用于花括号扩展的模式信息可以包含一个称为前导字符(preamble)的开头部分和一个称为附言(postscript)的结尾部分。花括号表达式本身可以包含一系列逗号分隔的字符串,也可以包含一系列整数或者单个字符。这里的模式信息不能包含内嵌的空白。下面的例子使用了一系列的整数。

56036f379b1f7a2c60d828179b1e6065.png

aba2b9463093bc9a5eed604c37879d8a.png

e33489668641dcb4815f1945543bac98.png
下面输出一系列逆序排列的字母。

花括号扩展支持嵌套。

2bf897231a5cacfbb6638b4eb78dd46f.png

那么花括号扩展一般应用在哪些地方呢?最普遍的应用是创建一系列的文件或者目录。比如说,摄影师有一个很大的图片集,想要按年份和月份来对这些图片进行分组,那么要做的第一件事就是创建一系列以年月格式命名的目录。这样,这些目录名将会按照年代顺序排列,输出目录的一个完整的列表。但是这样做工作量大,而且容易出错。为此我们可以这样操作。

859f98439d3fdc343ce7b4820208bed3.png

参数扩展

本章我们只是简要地介绍参数扩展(parameter expansion),参数扩展用在 shell 脚本中比直接用在命令行中更为有用。它的许多特性与系统存储小块数据以及给每个小块数据命名的性能有关。很多这样的小块数据(称为变量[variable]会更合适)可用于扩展。例如,命名为USER的变量包含你的用户名,为了触发参数扩展,并显示出USER的内容,你可以进行如下操作。

7dff403a55ddff0facd269bf5d29e81c.png

命令替换--$()

命令替换可以把一个命令的输出作为一个扩展模式使用,如下所示。

a4e503d3c78ab9536682bb5367492c21.png

9e68d1a4305b9c3e41b450ebc4e646f8.png
这里,把which cp命令的运行结果作为ls命令的一个参数,因此我们无需知道cp程序所在的完整路径就能获得cp程序对应的列表。

这个功能并不只是局限于简单的命令,也可以应用于整个管道中(只不过只显示部分输出内容)。

fe818637a34094364fe731a4e5338a61.png

2 引用--$

我们已经知道,shell有多种方式可以执行扩展,现在我们来学习如何控制扩展。先看下面的例子。符串。在第一个例子中,shell会对echo命令的参数列表进行单词分割(word splitting),去除多余的空白。在第二个例子中,因为$1是一个未定义的变量,所以参数扩展将把$1的值替换为空字shell提供了一种称为引用(quoting)的机制,用来有选择性地避免不想要的扩展。

fb2ace4cb03eb2cda49f34aaaf94ac26.png

双引号

我们要看的第一种引用类型是双引号(double quote)。如果把文本放在双引号中,那么shell使用的所有特殊字符都将失去它们的特殊含义,而被看成普通字符。字符“$”(美元符号)、“”(反斜杠)、“’”(反引号)除外。这就意味着单词分割、路径名扩展、波浪线扩展和花括号扩展都将失效,但是参数扩展、算术扩展和命令替换仍然生效。使用双引号能够处理文件名中包含空白的情况。假设不幸地有一个名为two words.txt的文件,如果在命令行中使用该文件名,那么单词分割功能将把它当成两个独立的参数,而不是当成我们希望的单个参数,具体运行结果如下所示。

a44cb2ff0be5faf7f82077b144f0f268.png
使用双引号可以阻止单词分割,得到预期的结果。另外,使用双引号甚至可以修复破损的文件名。

请记住,参数扩展、算术扩展和命令替换在双引号中依然生效:

9e82a2242e7502c093e2598d5d528b31.png

接下来,让我们看看双引号对字符替换的影响。我们首先深入了解一下单词分割是怎么工作的。在前面的例子中,我们已经看到单词分割去除文本中多余空白的情况,如下所示。默认情况下,单词分割会先查找是否存在空格、制表符以及换行(换行字符),然后把它们当作单词见的界定符(delimiter)。这就意味着没有用引号包含起来的空格、制表符和换行字符都不会被当成文本的一部分,而只是被当成分割符。因为它们把这些单词分割成不同的参数,所不会被当成文本的一部分,而只是被当成分割符。因为它们把这些单词分割成不同的参数,所以例子中的命令行被识别为命令后面跟着4个不同的参数。但是如果加上双引号,单词分割功能将失效,嵌入的空格将不再被当成界定符,而是被当成参数的一部分,如下所示。

e0f7325caefb2894e9421d9223c9f0a2.png

单词分割机制会把换行字符当成界定符,这一点在命令替换时将会产生微妙有趣的效果。参考下面的例子。

77c933c9462d7889fc3513b99e4bd9b6.png
在第一个例子中,没有加上引号的命令替换将导致命令行被识别为命令后面跟着38个参数;而在第二个例子中加了双引号,使得命令行被识别为命令后面只跟一个参数,这个参数包含着嵌入空格和换行字符。

单引号

如果我们希望抑制所有的扩展,那么应使用单引号。下面是不使用引号、使用双引号和使用单引号的情况对比。

15b21c4f0672153c56c9bc85e3fc06b4.png
可以看到,随着引用级别的加强,越来越多的扩展将被抑制。

转义字符

有时候我们只是想要引用单个字符。这种情况可以通过在该字符前加上反斜杠来实现。这里的反斜杠称为转义字符。转义字符经常在双引号中用来有选择性地阻止扩展。如下所示。

517dfea0ebcd071b9ca8496b102c0a51.png

转义字符也常用来消除文件名中某个字符的特殊含义。比如,文件名中可以使用在shell中通常具有特殊含义的字符。这些字符包括“$”、“!”、“&”、空格等。要想在文件名中包含特殊字符,可执行如下操作。

反斜杠除了作为转义字符外,也是一种表示法的一部分,这种表示法代表称为控制码的某些特殊字符。ASCII码表的前32个字符用来向电传打字类设备传送命令。其中有一些控制码很常见(比如制表符、退格符、换行符和回车符),但是其他的都不太常见(空字符、结束符和确认符),如表 2所示。

11c342796bbcdc21a0b769291ddf7e81.png
表中列出了一些常用的反斜杠转义字符序列。使用反斜杠来表示转义字符表示的理解来源于C语言,其他语言也采用了这种表示方法,包括shell。

在echo命令中带上-e选项,就能够解释转义字符序列。也可以将其放在“$ ‘ ’”

在echo命令中带上-e选项,就能够解释转义字符序列。也可以将其放在“$ ‘ ’”中。在下面的例子中,只需要使用sleep命令(它是一个简单的程序,在等待指定的秒数之后就会退出),就可以创建一个简单的倒计时的计时器:

74b094ba57770091f7398a6868c21a20.png

随着我们输入学习shell,就会发现扩展和引用的使用频率逐渐多起来,所以我们有必要很好地理解它们的工作方式。事实上,甚至可以说它们是shell中最重要的主题。如果不能正确地理解扩展,那么shell将会一直是个神秘和让人困惑的资源,它的潜在能力也就被浪费了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值