0
点赞
收藏
分享

微信扫一扫

Linux系统应用-glob通配及IO重定向

回顾: bash基础特性: 命令补全、路径补全、命令引用 文件或目录的复制、移动、删除 变量:变量类型 存储格式、数据范围、参与运算

bash的基础特性之七

globbing: 文件名通配机制


此前我们讲到过对Linux而言,一切皆文件。所有的我们可以使用的资源,甚至包括
硬件在Linux上统统组织为整个根文件系统上的某个路径下的某个文件。我们整个
Linux
在静态视角下无非就是一个文件系统下的诸多文件组成的一个所谓的系统而已。我们
把它称为文件系统。 另外一个从动态角度来看也无非就是一个运行中的内核,在内
核之上有,内核支配下的一个所谓的文件系统。所有动静两种角度并不太完全一样,
另外动态角度下内核是独立的,内核负责管控文件系统。在静态视角下内核自己也是
文件系统下的文件而已。既然如此我们对Linux管理操作主要是涉及到对文件的管理
操作,所有包括我们此前所讲到的命令,无非就是查看那个文件。

很多时候我们为了能够便捷操作,通常需要一次去操作多个文件所以这个时候我们就
需要文件名的通配机制来一次性的管理操作多个文件。 文件名通配指的是我们要编
写一种匹配模式,这个匹配模式之下能够用于实现多个文件名进行通配。

比如说:所有以.txt结尾的文件可以描述,文件名中只包含数字的文件,文件名中有
大写字母的文件等等。这种机制我们就称为文件名通配机制。我们用自然语言容易描
述但,接下来我们需要用计算机能够表示的机制。将我们自然语言的描述的模式,
用globbing来完成的这种机制。



globbing: 文件名通配机制(整体文件名匹配,而非部分)

匹配模式:元字符

元字符指的是什么呢?其实指的就是那些字符出现以后它并不表示字符本身的意义
而是用来匹配一定范围内的或者指定符合条件的字符。比如在Windows上我们都知
道 *(星号)匹配任意长度的任意字符。

比如:pa*就表示所有以pa开头的文件,这里是做字符串匹配的,意思就是文件名
中只要是pa开头的后面可以跟任意字符。pa、paa、passwd都是符合的。

我们想描述下文件名当中任意位置只要包含pa字符串就可以的文件怎么写呢?
*pa* 指文件名当中,中间只要有连续的两个pa字符前面可以出现任意字符后面也
可以出现任意字符。所以这种描述就称为文件名当中包含pa字符串出现在任何位置
都可以。

那我们想描述以pa字符串结尾怎么办呢?*pa来描述。

如果在描述为文件名中任意位置可以出现p或者a。 *p*a*

如果我们想定义长度怎么办?比如pa后面只能出现固定一个字符或者三个字符
使用来?:用于匹配任意单个字符。
因此像 pa?
pa是否符合条件?不符合的。单个字符代表必须得有一个字符。不管是什么
paa符合
passwd不符合的。不要看字符串的一部分,而要查看整体字符串。因为它是做
整个文件名匹配的。不能做部分文件名匹配这点要注意的。

因此我们想象下假如说我们匹配一个文件是这样子的,以pa结尾。pa前可以出现任
意两个字符。??pa。

p和a之间可以出现任意单个字符 p?a

p?a?: p后又单个字符a后有单个字符


比如:p和a之间出现一个数字

[]:匹配指定范围内的任意单个字符,有几种特殊格式比如说表示所有的字母
[a-z]大小写都可以,他们不区分大小写。如果表示所有数字就是[0-9]
所有的字母和数字就是[a-z0-9],对应的我们想匹配[abcxyz]这就表示他从
这6个字符中选出一个来,注意有且只能有一个。所以中括号是表示范围的。

pa后出现一个数字怎么描述呢? pa后出现两个数字呢?
pa[0-9] pa[0-9][0-9]

pa后200到290之间如何描述呢?
pa2[0-9][0-9]


匹配模式: 元字符
*: 匹配任意长度的任意字符
pa*,*pa*,*pa,*p*a*
?: 匹配任意单个字符
pa?,??pa,p?a,p?a?
pa,paa,passwd
[]:匹配指定范围内的任意单个字符
有几种特殊的格式:
[a-z],[A-Z],[0-9],[a-z0-9],[abcxyz]
在范围内不区分大小写,这个也是文件名通配机制

如果不得不指明大小写时:
[[:upper:]] :所有大写字母
[[:lower:]] :所有小写字母
[[:alpha:]] :所有字母
[[:digit:]] :所有数字
[[:alnum:]] :所有的字母和数字
[[:space:]] :所有空白字符
[[:punct:]] :所有标点符号

[^]:匹配指定范围外的任意单个字符
[^[:upper:]] :大写字符以外的任意字符,只要不是大写字母就行
[^0-9] : 匹配所有的非数字
[^[:alnum:]]: 匹配所有的非正常字符
[^a-z]:非字母


练习1:
显示/var目录下所有以l开头,以一个小写字母结尾,且中间出现一位任
意字符的文件或目录。
练习2: 显示/etc目录下,以任意一位数字开头,且以非数字结尾的文件或目录
练习3:显示/etc/目录下,以非字母开头,后面跟一个字母及其他任意长度任意字
符的文件或目录
练习4:复制/etc目录下,所有以m开头,以非数字结尾的文件或目录至
/tmp/megedu.com的目录
练习5:复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件
或目录至/tmp/man目录下
练习6: 复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或目录至
/tmp/conf.d 目录下

答案: 练习1: ls -d /var/l?[[:lower:]] -d是只显示目录本身,目录里的内容不显示

练习2: ls -d /etc/[0-9][^0-9]

练习3: ls -d /etc/[^a-z][a-z]

练习4: cp -r /etc/m*[^0-9] /tem/magedu.com/

练习5: cp -r /usr/share/man/man[0-9] /tmp/man/

练习6: cp -r /etc/[mnrp]*.conf /tmp/conf.d

IO重定向及管道

这个是bash的重要特性,管道的发明其实在unix的使用历史上非常重要,包括重定向
的机制实现。什么叫IO重定向的呢?程序是由指令加数据组成的。指令通常由程序来
提供数据从哪里来呢?所以一般来说程序中的数据可以由多种来源。比如在程序自己
内部有变量数组等数据结构直接提供。但这样一来通常意味着它数据的变化范围很小
。如果我们想灵活提供数据的话,我们可以通过文件提供数据这是第二种方式。

因此我们说过指令要加工的数据,其实这个数据不一定都是由程序来提供的,我们可以
通过外部的机制给指令提供数据,但是对于程序本身而言他们必须有一个位置。当你
没有指明从哪里获取数据的时候它能自动从哪里获取数据,以及我们没有指明数据
加工以后向何处输出时,它能够将加工后的结果保存至何处所以对于任何程序而言
也都有输入输出的概念,程序也要有IO。

程序: 指令+数据
程序:IO

什么叫重定向呢?
它本来有那么一个位置,但是我们把它改到别的位置了,所以叫做重定向。

可用输入的设备:文件
键盘设备、文件系统上的常规文件、网卡等
可用于输出的设备:文件
显示器、文件系统上的常规文件、网卡等

一般情况下没有给定输入输出设备是什么的时候,我们应该指定一个默认的输入输
出设备,只不过程序的数据流有3种。 第一种我们输入的数据流,如果我们没
指明时, 就有一个默认的叫做标准输入 (stdin)而默认情况下我们的标准输入
是键盘。输出的数据流,如果我们不指明时,标准输出(stdout),显示器。
错误的输出流--》错误输出(stderr),显示器

程序的数据流有三种:
输入的数据流:<--标准输入(stdio),键盘
输出的数据流:-->标准输出(stdout),显示器
错误输出流:-->错误输出(stderr),显示器

无论是命令的正常执行结果,还是错误执行结果最终都通过显示器来显示的原因

输出数据流指加工后的结果保存至何处,一旦在shell中一个命令运行失败了,这个
失败的消息该通过何种方式提醒给使用者这些都是很关键的。对于Linux而言我们还
要记住文件,一切皆文件而一个文件打开以后在内核中我们需要多次反复的引用到每
一个文件,因此对文件的标识是至关重要的。人容易识别的是名称字符字符串类的名
称,但机器更容易识别的是数字。

所以在系统内部通常会把每一个文件加载完成以后用唯一的一个数字来描述它表示它
,这个数字称为叫做fd:file descriptor,文件描述符。

文件描述符对于我们整个程序自己来讲,所以它的输入输出设备也都当作文件来表示
。而对于任何一个程序来讲它的标准输入通常用数字0来表示。标准输出用1来表示,
错误输出用2来表示。

fd:file descriptor,文件描述符
标准输入:0
标准输出:1
错误输出:2

IO重定向:

IO重定向指的是什么呢?Linux本来的标准输入是 键盘但是我现在要改成别的了。这
就叫做输入重定向。输出的位置本来是显示器,但是我们给它改成别的位置输出这
就叫做输出重定向。

输出重定向,输出重定向的实现非常简单我们只需要使用所谓的大于号>即可进行表示
这就表示一个命令的结果不在显示到默认位置,而是改为显示在其他位置。但是我么
有说过对Linux而言一切皆文件。所以命令的输出结果我们可以通过一个输出重定向
导出到一个文件去,但这个文件可能代表的是常规文件,也有可能代表是另一个设备
都是有可能的。

注意这个命令非常危险,比如cat /etc/issue > /dev/sda 这样可能会干掉
硬盘上所有的文件。所以不要轻易尝试。

但是这种输出重定向有一个称呼叫做覆盖输出重定向。什么叫覆盖输出就是你所指明
的那个原有的文件中本来所有的内容被覆盖掉而且是不会打招呼的。是非常危险的。

特殊设备: /dev/null
特殊设备用作输出重定向非常好用,/dev/null我们通常称为未通,也叫数据
黑洞。因为这个地方这个软设备是个假设备任何设备送给它,它都会悄悄得丢弃而且
不泛起一点涟漪。所以对我们来讲将来有些输出得数据没有任何意义时我们都可以输
出重定向至/dev/null

通过这个可以知道命令运行得状态结果,是成功了还是失败了 echo $?
这个是非常重要的。
输出重定向: >
特性:覆盖输出
输出重写向:>>
特性:追加输出。保留原有文件的内容

set命令: -C: 禁止覆盖输出重定向至已存在的文件

此时可使用强制覆盖输出: >|

cat /etc/issue >| /tmp/issue2.out
加了|表示强制重定向覆盖文件

+C: 关闭上述特性


错误输出流重定向: 2>
2>>是追加输出


合并正常输出流和错误输出流:
使用 &>,&>> 即可

我们把正常输出定向到一个位置,但是把错误输出定向至正常输出上。因此不管是
正常的还是错误的都会输出到一个位置 。

(1)&>,&>>
(2)COMMAND > /path/to/somefile 2>&1
COMMAND >> /path/to/somefile 2>&1

输入重定向: <

其实大多数命令本身都能直接带参数以文件当参数,所以大多数命令都不需要使用输
入重定向就能够从文件中输入数据了。

tr命令:
tr [OPTION]...SET1[SET2]
把输入的数据当中的字符,凡是在SET1定义范围内的出现的,通通对位
转换为SET2出现的字符。

tr abc ABC这是什么意思呢?这就表示你给的字符出现了a统统换成大A
小b统统换大B,小c统统换成大C所以叫对位替换。

tr命令还有另外一个作用,如果我们不给第二个字符集的时候。比如说:
tr -d 'abc' < /etc/issue

用法1:
tr SET1 SET2 < /PATH/FROM/SOMEFILE
用法2:
tr -d SET1 < /PATH/FROM/SOMEFILE
从某个文件读取数据之后进行转换,他不会修改你的原文件只会把文件的数据
读出来之后进行修改后输出到屏幕上来。
注意: 不修改原文件

如果是两个小于号意味着什么?

<<:表示 Here Document 此处创建文档。

比如 cat << EOF

把我们给的数据重新输出一遍,它能够让我们自己换行输入完所有数据并指明结
束符。EOF表示结束符意思是我们所有输入都结束了,把这些内容打包一次性的
输出。这个有什么用呢?

cat > /tmp/cat.out << END

它可以把我们输入的数据可以创建为文档。

cat << EOF
cat > /PATH/TO/SOMEFILE <<EOF

管道: 我们刚才输入和输出重定向都是把一个命令的结果给他保存到一个文件中或者从一个文件中读出数据。那我们能不能把一个命令的直接送给另外一个命令。

每个命令都有输入输出所以叫IO或者每个程序都有输入输出所以我们称为程序的IO
那我们可不可以这样想,把前一个程序的输出当后一个命令的输入我们把他们链接起
来。这个就是管道

作用:连接程序,实现将前一个命令的输出直接定向后一个程序当作输入数据流
COMMAND1 | COMMAND2 | COMMAND3 | ...

Linux重要哲学思想之一组合小程序完成复杂任务

who | head -2

who | head-2 tr 'a-z' 'A-Z' | tr -d '0-9'

tee 命令 COMMAND | tee /PATH/TO/SOMEFILE 它能够将COMMAND的结果输出到屏幕上并且有保存至指明文件中一份

练习1: 把/etc/passwd文件得前6行信息转换为大写字符后输出 head -n 6 /etc/passwd |tr 'a-z' 'A-Z'

命令总结: tr,tee

举报

相关推荐

0 条评论