19 Star 186 Fork 90

baoke / Linux学完就忘系列

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
08.glob通配及IO重定向.md 7.39 KB
一键复制 编辑 原始数据 按行查看 历史
baoke 提交于 2021-04-19 15:40 . update 08.glob通配及IO重定向.md.

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

匹配模式:元字符
:匹配任意长度的任意字符
pa
,pa,*pa,pa

?:匹配任意单个字符 pa?,??pa,p?a,p?a?

#匹配pa开头
ls /etc/pa*
#指定-d:代表不显示匹配文件夹下的文件
ls -d /etc/pa*
#匹配pa后4个字符
ls -d /etc/pa????
#匹配。log结尾
ls /var/log/*.log

[]:匹配指定范围内的任意单个字符
有几种特殊格式:
[a-z],[A-Z],[0-9],[a-z0-9]
[[:upper:]]:所有大写字母
[[:lower:]]:所有小写字母
[[:alpha:]]:所有字母
[[:digit:]]:所有数字
[[:alnum:]]:所有字母和所有数字
[[:space:]]:所有空白字符
[[:punct:]]:所有的标点符号

#匹配p和a之间有标点符号的文件
ls p[[:punct:]]a

#创建一个中间有空白字符的文件
touch p\ a
#匹配中间有空白字符的文件
ls ?[[:space:]]?

[^[:upper:]] 匹配非大写字母
[^[0-9]] 匹配非数字 [^[:alnum:]] 匹配非正常字符

练习1:显示/var目录所有以l开头,以一个小写字母结尾,且中间出现一位任意字符都是文件或目录

ls -d /var/l?[[:lower:]]

练习2:显示/etc目录下,以任意一位数字开头,且以非数字结尾的文件或目录

ls -d /etc/[0-9]*[^0-9]

练习3:显示/etc/目录下,以非字母开头,后面跟一个字母及其他任意长度任意字符的文件或目录

touch /etc/1Ac /etc/2b777
ls -d /etc/[^a-z][a-z]*
ls -d /etc/[^[:alpha:]][[:alpha:]]*

练习4:复制/etc目录下,所有一m开头,以非数字结尾的文件或目录至/tmp/abc.com目录

mkdir /tmp/abc.com
cp -r /etc/m*[^0-9] /tmp/abc.com

练习5:复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录至/tmp/man/目录下

mkdir /tmp/man
cp -r /usr/share/man/man[0-9] /tmp/man
#查看复制过去的文件占的硬盘空间
du -sh /tmp/man

练习6:复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或者目录至/tmp/conf.d/目录下

mkdir /tmp/conf.d
cp -r /etc/[mnrp]*.conf /tmp/conf.d

IO重定向及管道

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

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

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

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

IO重定向:

输出重定向:

覆盖输出 >
追加输出 >>

cat /etc/issue > /tmp/issue.out

输出重定向到虚拟终端tty2上:

cat /etc/issue > /dev/tty2

虚拟终端tty2的显示:

set -C
禁止覆盖输出重定向至已存在的文件
此时可使用强制覆盖输出:>|

强制覆盖输出

cat /etc/issue >| /tmp/issue.out

set +C
关闭禁止覆盖输出重定向至已存在的文件

错误输出流重定向: 2>, 2>>
以下不存在的文件或目录的错误信息输出到了/tmp/abc.out文件中

合并正常输出流和错误输出流:&>,&>>

#正常输出流
cat /etc/issue &>> /tmp/abc.out
#错误输出流
cat /etc/issue1 &>> /tmp/abc.out

合并正常输出流和错误输出流另一种方式:
COMMAND > /path/to/somefile 2>&1
COMMAND >> /path/to/somefile 2>&1

#正常输出流
cat /etc/issue >> /tmp/issue5.out 2>&1
#错误输出流
cat /etc/issue5 >> /tmp/issue5.out 2>&1

输入重定向 <

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

用法1: tr SET1 SET2 < /PATH/FROM/SOMEFILE

#将输入/etc/issue文件内容所有小写字母转换为大写字母,并输入重定向到显示器
tr [a-z] [A-Z] < /etc/issue

用法2:
tr -d SET1 < PATH/FORM/SOMEFILE

#这里-d指的是删除;这里是指删除所有大写字母,并输入重定向到显示器  
tr -d '[A-Z]' < /etc/issue

注意:tr命令不删除原文件

Here Document:<<
cat << EOF

cat <<EOF
> abc
> cde
> jge
> EOF

cat > /PATH/TO/SOMEFILE << EOF

#输入重定向到文件test1.out,且使用cat将文件信息打印到显示器
cat > /tmp/test1.out <<OF
> abc
> cde
> OF

使用tee也可以做到上面的效果(tee:从标准输入写往文件和标准输出)

tee /tmp/test2.out <<EOF
> hello
> world
> EOF

管道

连接程序,实现前一个命令的输出直接定向后一个程序当做输入
COMMAND1 | COMMAND2 |COMMAND3 | ...

#cat /etc/issue的输出结果作为tr 'a-z' 'A-Z'的输入
cat /etc/issue|tr 'a-z' 'A-Z'
#只看登录的前2个用户
who|head -2
#只看登录的前2个用户,且将所有的小写字母转换为大写
who|head -2|tr 'a-z' 'A-Z'
#接上条命令,加入删除0-9数字
who|head -2|tr 'a-z' 'A-Z'|tr -d '0-9'

tee命令:将COMMAND结果输出到屏幕上,同时保存到文件中

COMMAND|tee /PATH/TO/SOMEFILE

#将/etc/issue输出结果送给tee,让tee保存到issue.tee文件里,同时会再发一次数据流给tr
cat /etc/issue|tee /tmp/issue.tee|tr 'a-z' 'A-Z'
#如果想保存文件中,又打印到显示器
cat /etc/issue|tee /tmp/issue.tee

练习1:把/etc/passwd文件的前6行的信息转换为大写字符后输出;

head -6 /etc/passwd|tr 'a-z' 'A-Z'

特殊设备:/dev/null

将来如果有些输出数据没有任何意义时,都可以输出重定向至/dev/null

#假设我只关心命令成功和失败,不关心输出是什么的时候,使用合并重定向到/dev/null
#在shell编程中经常用这种方式来获取它的状态,来判断是否继续执行某段程序代码.0:代表成功、1-255:代表失败
ls /var &> /dev/null
#0代表成功
echo $?

ls /varr &> /dev/null
#1-255代表失败
echo $?

cat <<EOF与cat <<-EOF的区别

两个都是获取stdin,并在EOF处结束stdin,输出stdout。

但是<<-是什么意思呢?

先来看man中的说明:

If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter.

翻译过来的意思就是:如果重定向的操作符是<<-,那么分界符(EOF)所在行的开头部分的制表符(Tab)都将被去除。

这可以解决由于脚本中的自然缩进产生的制表符。

通俗一点的解释:

在我们使用cat <<EOF时,我们输入完成后,需要在一个新的一行输入EOF结束stdin的输入。EOF必须顶行写,前面不能用制表符或者空格。

比如,下面的语句就不会出错:

cat <<EOF
Hello,world!
EOF

如果结束分解符EOF前有制表符或者空格,则EOF不会被当做结束分界符,只会继续被当做stdin来输入。
而<<-就是为了解决这一问题:

cat <<-EOF
Hello,world!
      EOF

上面的写法,虽然最后的EOF前面有多个制表符和空格,但仍然会被当做结束分界符,表示stdin的结束。
这就是<<和<<-的区别。

Shell
1
https://gitee.com/abcd1234567_1/linux.git
git@gitee.com:abcd1234567_1/linux.git
abcd1234567_1
linux
Linux学完就忘系列
master

搜索帮助