摘要:此文涉及到通配符*,[],?,[^],以及重定向>,>>,2>,2>>,&>,&>>,<,<< EOF,tr,tee,管道,set等命令使用
此为Sunny,王苗苗同学的学习笔记,持续学习,持续分享,持续进步,向着大神之路前进
globbing:文件名通配,匹配整体的文件名,而非部分
*:匹配任意长度的任意字符
pa*:匹配pa开头的所有文件
*pa*:匹配中间包含pa的文件
*pa:匹配以pa结尾的文件
*p*a*:匹配含p及a(p在前a在后)的文件
?:匹配任意单个字符
pa?:匹配文件名为3位,由pa以及其他任意一位组成
??pa:匹配文件名为4位,前两位为任意,最后两位为pa
p?a:匹配文件名为3位,有p,任意一位,a组成
p?a?:匹配文件名为4位,p、任意一位、a、任意一位
[ ]:匹配指定范围内的任意单个字符
有几种特殊格式:
[a-z]:[A-Z]:匹配任意一个字母,不区分大小写
[abcd123]:匹配abcd123中的任意一个字符
[0-9]:匹配任意一个0-9的数字
[a-z0-9]:匹配任意一个字母或数字
[[:upper:]]:匹配任意一个大写字母
[[:lower:]]:匹配任意一个小写字母
[[:alpha:]]:匹配所有字母
[[:digit:]]:匹配所有数字
[[:alnum:]]:匹配所有字母和数字
[[:space:]]:所有空白字符
[[:punct:]]:所有标点符号
[^]:匹配指定范围外的任意单个字符,相当于上一个取反
[^[:upper:]]:匹配不含大写字母
[^0-9]:匹配不含数字
[^[:alnum:]]:匹配不含字母和数字
练习1:显示/var目录下所有以l开头,以一个小写字母结尾,且中间出现一位任意字符的文件或目录;
ls -d /var/l?[[:lower:]]
练习2:显示/etc目录下,以任意一位数字开头,且以非数字结尾的文件或目录;
ls -d /var/[0-9]*[^0-9]
练习3:显示/etc目录下,以非字母开头,后面跟一个字母及其它任意长度任意字符的文件或目录;
ls -d /etc/[^a-z][a-z]*
练习4:复制/etc目录下,所有以m开头,以非数字结尾的文件或目录至/tmp/test目录;
cp -r /etc/m*[^0-9] /tmp/test/
练习5:复制/usr/share/man目录下,所有以man开头,后跟一个数字结尾的文件或目录至/tmp/man/目录下;
cp -r /usr/share/man/man[0-9] /tmp/man/
练习6:复制/etc目录下,所有以.conf结尾,且以m,n,r,p开头的文件或目录至/tmp/conf.d/目录下;
cp -r /etc/[mnrp]*.conf /tmp/conf.d/
IO重定向及管道
程序:指令+数据
sunny理解:所谓的IO其实就是input跟output,也就是输入输出,做好的程序其实就是一堆的写好的指令,你去使用程序,其实就是看你给它输入什么东西,然后预期它会产出什么东西。所以输入输出是一个很重要的东西。
Linux中一切皆文件,连硬件设备都已经被虚拟化成为了文件,那么Linux中常见的输入输出设备有哪些呢?
可用于输入的设备:键盘设备、文件系统上的常规文件、网卡等。
可用于输出的设备:显示器、文件系统上的常规文件、网卡等。
程序的数据流有三种:
输入的数据流:<-- 标准输入(stdin),键盘
输出的数据流:–> 标准输出(stdout),显示器
错误输出流: --> 错误输出(stderr),显示器
错误的输出流,不是命令本身输出的数据流,而是解释器辅助输出的错误信息,例如ls /var是标准输出,但是如果输入lss /var 提示找不到命令,这个就是bash输出的错误信息。
fd:file descriptor 文件描述符
标准输入:0
标准输出:1
错误输出:2
IO重定向
输出重定向: >, >>
输出重定向:> 此为覆盖输出
输出重定向:>> 此为追加输出
因为>特别危险,例如,运行cat “XXX”> /dev/sda 那你的一块硬盘就可能因此报废。因为可能会覆盖掉重要的文件,那么能不能禁用此操作呢?可以使用set命令
set -C:禁止覆盖输出重定向至已存在的文件;如果仍然想强制覆盖可使用>|
set +C:关闭上述特性。
#查看文件内容
[root@redhat tmp]# cat sunny.txt
hello sunny
hello sunny
[root@redhat tmp]# echo "how are you " >> sunny.txt
#追加写入,查看追加的内容加在文件末尾
[root@redhat tmp]# cat sunny.txt
hello sunny
hello sunny
how are you
#覆盖写入
[root@redhat tmp]# echo "how are you " > sunny.txt
#查看文件只有覆盖后的内容
[root@redhat tmp]# cat sunny.txt
how are you
#设置为如果文件存在,不允许覆盖
[root@redhat tmp]# set -C
#再写入会提示错误,不允许覆盖写入
[root@redhat tmp]# echo "how are you ?" > sunny.txt
bash: sunny.txt: cannot overwrite existing file
#使用>|强制覆盖写入
[root@redhat tmp]# echo "how are you ?" >| sunny.txt
#查看文件已被强制覆盖
[root@redhat tmp]# cat sunny.txt
how are you ?
#使用set +C 关闭不允许强制覆盖的设置
[root@redhat tmp]# set +C
#覆盖写入成功
[root@redhat tmp]# echo "how are you ? hahahah" > sunny.txt
[root@redhat tmp]# cat sunny.txt
how are you ? hahahah
错误输出重定向: 2> , 2>>
合并正常输出流和错误输出流:&>,&>>
[root@redhat tmp]# cat haha
jhjkdhkhkdhkjhdkhkhksjk
#将haha文件内容重定向输出指sunny.txt
[root@redhat tmp]# cat haha > sunny.txt
[root@redhat tmp]# cat sunny.txt
jhjkdhkhkdhkjhdkhkhksjk
#cat 目录,报错
[root@redhat tmp]# cat conf.d/ > sunny.txt
cat: conf.d/: Is a directory
#查看文件,发现没写进任何东西,这是因为>只是标准输出,不负责错误输出
[root@redhat tmp]# cat sunny.txt
#使用2>进行错误输出
[root@redhat tmp]# cat conf.d/ 2> sunny.txt
#查看收集到的错误输出信息
[root@redhat tmp]# cat sunny.txt
cat: conf.d/: Is a directory
#使用>>进行追加输出
[root@redhat tmp]# cat haha >> sunny.txt
[root@redhat tmp]# cat sunny.txt
cat: conf.d/: Is a directory
jhjkdhkhkdhkjhdkhkhksjk
#使用2>> 进行错误信息追加输出
[root@redhat tmp]# cat hehe 2>> sunny.txt
[root@redhat tmp]# cat sunny.txt
cat: conf.d/: Is a directory
jhjkdhkhkdhkjhdkhkhksjk
输入重定向:<
这个用得比较少,不做过多陈述。
tr命令:tr [OPTION]… SET1 [SET2]
把输入的数据当中的字符,凡在SET1定义范围内出现,通通对应转换为SET2出现的字符,此命令不修改原文件内容,只做输出转换。
用法1 :替换 tr SET1 SET2
例如把小写字母全部替换为大写;
用法2:删除指代内容。tr -d SET1
[root@redhat tmp]# cat sunny.txt
cat: conf.d/: Is a directory
jhjkdhkhkdhkjhdkhkhksjk
cat: hehe: No such file or directory
#将小写字母全替换为大写字母
[root@redhat tmp]# cat sunny.txt | tr [a-z] [A-Z]
CAT: CONF.D/: IS A DIRECTORY
JHJKDHKHKDHKJHDKHKHKSJK
CAT: HEHE: NO SUCH FILE OR DIRECTORY
#替换只是显示替换,并没有替换文件内容,查看文件内容,仍然是小写的
[root@redhat tmp]# cat sunny.txt
cat: conf.d/: Is a directory
jhjkdhkhkdhkjhdkhkhksjk
cat: hehe: No such file or directory
#删除文件中所有的c
[root@redhat tmp]# cat sunny.txt | tr -d [c]
at: onf.d/: Is a diretory
jhjkdhkhkdhkjhdkhkhksjk
at: hehe: No suh file or diretory
#使用输入重定向
[root@redhat tmp]# tr -d [cat] < sunny.txt
: onf.d/: Is direory
jhjkdhkhkdhkjhdkhkhksjk
: hehe: No suh file or direory
<< :代表此处创建文档Here Document
#下面的意思就是,写入多行数据,直到遇到结束符EOF前,(EOF可以定义为任何,这是现在习惯把EOF当为结束符)
[root@redhat tmp]# cat << EOF
> here document
> hello
> how are you
> you are sunny ?
> EOF
here document
hello
how are you
you are sunny ?
#可以看到把上面多行信息,一起输出
#如果想把多行信息输入一个文件,可以使用下述命令,向sunny.txt中写入多行数据
[root@redhat tmp]# cat <<EOF >> sunny.txt
> here document
> hello
> how are you
> you are sunny ?
> EOF
[root@redhat tmp]# cat sunny.txt
cat: conf.d/: Is a directory
jhjkdhkhkdhkjhdkhkhksjk
cat: hehe: No such file or directory
here document
hello
how are you
you are sunny ?
管道 |:连接程序,实现将前一个命令的输出直接定向到后一个程序的输入
COMMAND1 | COMMAND2 | COMMAND3 | …
程序A输入数据,把输出的文件内容保存到一个地方,然后程序B到那个地方读取文件,作为程序B的输入。这个过程中文件是不是可以省掉呢,变为如下图。这就是管道的作用,将前一个命令的输出变为下一个命令的输入。
tee命令:从标准输入读数据,然后写入标准输出和文件。上面说tr命令只会写到标准输出而不会将结果保存到文件中,而tee则既能将内容写进标准输出,又可以将其保存到文件中,实现一道输入,两道输出。
# 把haha为文件内容既保存在sunny.txt文件中,又写到输出中
[root@redhat tmp]# cat haha | tee sunny.txt
jhjkdhkhkdhkjhdkhkhksjk
[root@redhat tmp]# cat sunny.txt
jhjkdhkhkdhkjhdkhkhksjk
#将内容既写进sunny.txt文件中,又作为标准输出送给下一个命令当输入
[root@redhat tmp]# echo "hello sunny" | tee sunny.txt | tr [a-z] [A-Z]
HELLO SUNNY
[root@redhat tmp]# cat sunny.txt
hello sunny