本篇博文依然涉及到bash的基本特性 文件名通配,并讲解IO重定向以及管道的使用 管道配合tr命令的应用


bash的基础特性之一:文件名通配

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

   匹配模式:元字符

*:匹配任意长度的任意字符

pa*,*pa*,*pa,*p*a*

?:匹配任意单个字符

pa?,??pa,p?a,p?a?

[];匹配指定范围内的任意单个字符

有几种特殊字符:

[a-z],[A-Z],[0-9],[a-z0-9]

[[:upper:]]:所有大写字母

[[:lower:]]:所有小写字母

[[:alpha:]]:所有字母

[[:digit:]]:所有数字

[[:alnum:]]:所有的字母和数字

[[:punct:]]:所有标点符号

[[:space:]]:空白字符

[[:space:]]:空格

 pa[0-9][0-9],2[0-9][0-9]

[^]:匹配指定范围外的任意单个字符

[^[:upper:]]:所有大写字母外

[^[:space:]]:空白字符外

[^[:alnum:]]:所有的字母和数字外

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

root@wen-7 shell]# ls -d  /var/1?[[:lower:]]
/var/1aa

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

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

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

[root@wen-7 shell]# ls  -d /etc/[^a-z][a-z]*
/etc/2afd1  /etc/2qq
[root@wen-7 shell]#

4. 复制/etc/目录下,所有以m开头,以非数字结尾的文件后目录至/tmp/magedu.com目录

[root@wen-7 shell]# cp -r  /etc/m*[^0-9] /tmp/magedu.com/
[root@wen-7 shell]# ls /tmp/magedu.com/
machine-id  mail.rc                   maven        modprobe.d      mtab         my.cnf
magic       makedumpfile.conf.sample  mime.types   modules-load.d  mtools.conf  my.cnf.d
/

5.  复制/usr/share/man目录下,所有以m开头,后根一个数字结尾的文件后目录至/tmp/man目录下

[root@wen-7 shell]# cp -r /usr/share/man/m*[0-9] /tmp/man
[root@wen-7 shell]# ls /tmp/man
man1  man2  man3  man4  man5  man6  man7  man8  man9

6. 复制/etc/目录下,所有以.conf开头,且以m,n,r,p开头的文件后目录至/tmp/conf.d

[root@wen-7 shell]# cp -r /etc/[mnrp]*.conf /tmp/conf.d/
[root@wen-7 shell]# ls /tmp/conf.d/
man_db.conf  named.conf     ntp.conf      pcp.conf      request-key.conf  rsyslog.conf
mke2fs.conf  nfsmount.conf  numad.conf    pnm2ppa.conf  resolv.conf

IO重定向及管道:

程序:指令+数据

程序:IO 

    可用于输入的设备:文件(键盘设备,文件系统上的文件,网卡等)

    可用于输出的设备:文件(显示器,文件系统上的文件,网卡等)

程序的数据流有三种:

    输入的数据流:<------标准输入(stdin),默认输入是键盘;

    输出的数据流:------->标准输出(stdout),默认是显示器;

    错误输出流:-------->标准输出(stderr),默认是显示器;

fd:file descriptor:文件描述符

文件在打开后,在内核中反复调用文件

系统在每一个文件加载完成后,用唯一一个数字来标识文件,这个数字叫做fd

    标准输入:0

    标准输出:1

    错误输出:2


IO重定向:把标准输入输出改变位置

输出重定向: >       

        特性:覆盖输出   注意:不要对硬盘设备/dev/sd* 重定向 会清空磁盘

        使用 set -c命令, 禁用覆盖输出重定向至已存在的文件; 此时可使用强制覆盖输出:>|

            只对当前shell 有效    

        使用 set +c命令, 启用覆盖重定向功能

输出重定向: >>

        特性:追加输出 原有的内容后面追加  建议使用

错误输出流重定向:2>,2>> 

[root@wen-7 shell]# cat /etc/issueq 2> /tmp/issosut.out 
[root@wen-7 shell]# cat /tmp/issosut.out 
cat: /etc/issueq: 没有那个文件或目录
[root@wen-7 shell]# cat /etc/issueq 2>> /tmp/issosut.out 
[root@wen-7 shell]# cat /tmp/issosut.out 
cat: /etc/issueq: 没有那个文件或目录
cat: /etc/issueq: 没有那个文件或目录

合并多个程序的输出:

    (COMMAND1;COMMAND2) > /POTH/TO/SOMEFILE

[root@wen-7 shell]# (cat /etc/issue;cat /etc/redhat-release ) > /tmp/iss
issosut.out  issue.out    
[root@wen-7 shell]# (cat /etc/issue;cat /etc/redhat-release ) > /tmp/issosut.out 
[root@wen-7 shell]# cat /tmp/issosut.out 
#\S
#Kernel \r on an \m
#$hostname
#date
CentOS Linux release 7.2.1511 (Core)

    

合并正常输出流和错误输出流:

1.&> ,&>>   不管命令正确或失败

[root@wen-7 shell]# cat /etc/issue &>> /tmp/issosut.out 
[root@wen-7 shell]# cat /tmp/issosut.out 
#\S
#Kernel \r on an \m
#$hostname
#date
cat: /etc/issueq: 没有那个文件或目录
cat: /etc/issueq: 没有那个文件或目录
#\S
#Kernel \r on an \m
#$hostname
#date

2.2&>1

[root@wen-7 shell]# cat /etc/issueq >> /tmp/issosut.out 2>&1
[root@wen-7 shell]# cat /tmp/issosut.out 
#\S
#Kernel \r on an \m
#$hostname
#date
cat: /etc/issueq: 没有那个文件或目录

特殊设备:

/dev/null:空设备,可以屏蔽信息 

        可以凭借命令的执行状态结果,进行判断

[root@wen-7 shell]# head -n1 /etc/passwd &>/dev/null
[root@wen-7 shell]# echo $?0

/dev/zero:造0机,重复造0

输入重定向:<

tr命令:

    tr [options].....SET1[SEF2]

        把输入的数据中的字符,凡是在SEF1定义的范围中,通通对位转换为SEF2出现的字符

[root@wen-7 shell]# tr [a-z] [A-Z]
how are you
HOW ARE YOU
hello world
HELLO WORLD
123
123

        不接受指定位置,只能输出重定向

[root@wen-7 shell]# tr [a-z] [A-Z] < /etc/issue
#\S#KERNEL \R ON AN \M
#$HOSTNAME
#DATE

    用法:tr sef1 sef2  < /PATH/TO/SOMEFILE

                tr  [options] sef1 <  /PATH/TO/SOMEFILE

 选项:

        -d:删除指定字符集合中的字符

        -s: 把连续重复的字符以单独一个字符表示

        -t:将第一个字符集对应字符转化为第二字符集对应的字符


输入重定向:<<

    here Document:

        cat  <<EOF

        cat > / PATH/TO/SOMEFILE  << EOF 

        输出创建文件:

[root@wen-7 shell]# cat > /tmp/cat.sh << EOF
> how are you
> what are you doing
> END
> EOF
[root@wen-7 shell]# cat /tmp/cat.sh 
how are you
what are you doing
END

           脚本打印列表:

[root@wen-7 shell]# cat s.sh 
#!/bin/bash
cat << EOF
hello world
hello wen
hello user
EOF

管道:

使用符号“|“表示

 连接程序,实现将前一个命令的输出直接定向到后一个程序当做输入,可连接多次

    COMMAND1 | COMMCND2 | COMMAND3.。。。

[root@wen-7 shell]# cat /etc/issue | tr [a-z] [A-Z]
#\S
#KERNEL \R ON AN \M
#$HOSTNAME
#DATE
[root@wen-7 shell]# who| head -2| cut  -d" " -f1
root
root

   错误输出默认不能通过管道转发,可利用2>&1| 或|&实现     

[root@wen-7 shell]# ca /tmp/issosut.out |& tr 'a-z' "A-Z" 
BASH: CA: 未找到命令...
相似命令是::
'AC'
'SA'
[root@wen-7 shell]# ca /tmp/issosut.out 2>&1| tr 'a-z' "A-Z" 
BASH: CA: 未找到命令...
相似命令是::
'AC'
'SA'

扩展用法:

   1.less:一页一页查看

        $ls -l /etc|less

   2.通过电子邮件发送输入

        $echo "test mail"|mail \

            -s "test" root@example.com

    3.lpr:把输入发送给打印机

            $echo "test print" | lpr -P printer_name

tee命令:

保留命令的输出结果保留到文件中,并把结果在输出到屏幕上

使用:

    保存不同阶段的输出

    复杂管道的故障排除

    同事查看和记录输出

[root@wen-7 shell]# cat /etc/issue | tee /tmp/issue.out 
#\S
#Kernel \r on an \m
#$hostname
#date
[root@wen-7 shell]# cat /tmp/issue.out 
#\S
#Kernel \r on an \m
#$hostname
#date

并能再递到后面的命令

[root@wen-7 shell]# cat /etc/issue | tee /tmp/issue.out 
#\S
#Kernel \r on an \m
#$hostname
#date
[root@wen-7 shell]# cat /tmp/issue.out 
#\S
#Kernel \r on an \m
#$hostname
#date

练习:

    1.把/etc/passwd/文件中的前6行的信息转换成大写输出到屏幕上

[root@wen-7 shell]# head -n6 /etc/passwd | tr 'a-z' 'A-Z'
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN
ADM:X:3:4:ADM:/VAR/ADM:/SBIN/NOLOGIN
LP:X:4:7:LP:/VAR/SPOOL/LPD:/SBIN/NOLOGIN
SYNC:X:5:0:SYNC:/SBIN:/BIN/SYNC

链接文件的区别:

软链接文件中,链接文件保存的只是源文件的文件名和文件路径,用户访问链接文件,实则跳转至源文件,相当于windows的快捷方式

硬链接文件中,链接文件保存的是源文件的所有数据,相当于源文件的备份

inode的工作原理:

用 户创建一个文件,系统会自动分配一个inode号,inode号是文件系统下的inode表的编号,每个inode号对应的记录中包含文件的元数据和数据指向关系,系统会在文件创建时,依据文件的大小自动选择指针类型,来在inode表中指明数据块地址,文件大小小于4k,选择直接块指针,大于4k选择,并是1024的倍数,系统会自动使用间接块指针,双重间接块指针,三层间接块指针,每一层多出4*1024*1024的大小

练习:

1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中

[[root@wen-7 ~]# tr [a-z] [A-Z] < /etc/issue > /tmp/issue.out 
[root@wen-7 ~]# cat /tmp/issue.out 
#\S
#KERNEL \R ON AN \M
#$HOSTNAME
#DATE

2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中

[root@wen-7 ~]# echo `who` | tr [a-z] [A-Z] > /tmp/who.out 
[root@wen-7 ~]# cat /tmp/who.out 
ROOT PTS/0 2016-07-28 08:19 (10.1.250.47) ROOT PTS/1 2016-07-28 17:54 (10.1.250.47)
[root@wen-7 ~]#

3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:

Hello, I am 用户名,the system version is here,pleasehelp me to check it ,thanks!

操作系统版本信息

[wen@wen-7 ~]$ echo “Hello, I am $HOSTNAME ,the system bersion is here,pleasehelp me tanks! `cat /etc/redhat-release` | 
> mail -s help root
Message 14:
From wen@wen-7.localdomain  Thu Jul 28 20:54:15 2016
Return-Path: <wen@wen-7.localdomain>
X-Original-To: root
Delivered-To: root@wen-7.localdomain
Date: Thu, 28 Jul 2016 20:54:15 +0800
To: root@wen-7.localdomain
Subject: help
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=utf-8
From: wen@wen-7.localdomain (wen)
Status: R
“Hello, I am wen-7 ,the system bersion is here,pleasehelp me tanks! CentOS Linux release 7.2.1511 (Core)

4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开

[root@wen-7 ~]# ls /root/ | tr "\n" "\040"
passwd.bak qwe.file qwe.txt shell 上课网络环境.txt [root@wen-7 ~]# 
[wen@wen-7 ~]$ ls /root/ | tr "\n" "\040"

5、file1文件的内容为:”1 2 3 4 5 6 7 8 9 10” 计算出所有数字的总和

[root@wen-7 ~]# i=$((`tr " " "+" < file1`));echo $i
55
[root@wen-7 ~]# cat file1 
1 2 3 4 5 6 7 8 9 10

6、删除Windows文本文件中的'^M'字符

[root@wen-7 ~]# cat -A 上课网络环境.txt | tr ‘^M’ "\015"
$
$<tp
$ftp://10.1.0.1
$
$e
$10.1.X.Y
$255.255.0.0
$10.1.0.1
$
$;
$root
$mageedu
$c0G
$
$ 10.1.100.1
$
$ftp://10.1.0.1/pub/Tools/
$
$<
$geEdu(1)
Zlinuxedu@foxmail.com[root@wen-7 ~]#

7、处理字符串“xt.,l 1 jr#!$mn2 c*/fe3 uz4”,只保留其中的数字和空格

[root@wen-7 ~]# echo "xt.,l 1 jr#$summn2 c*/fe3 uz4" | tr "a-z" " "| tr "[[:punct:]]" " "
      1          3   4

8、将PATH变量每个目录显示在独立的一行

[root@wen-7 ~]# echo $PATH| tr ":" "\n"
/usr/lib64/qt-3.3/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin

9、删除指定文件的空行

[root@wen-7 shell]# cat filist.sh 
#!/bin/bash
echo "通过命令传递两个文本,计算空白行之和"
[ $# -lt 2 ] && echo "2 ge canshu" && exit 1
fuo1=$(grep "^$" $1|wc -l)
fun2=$(grep "^$" $2|wc -l)
echo "tolal blank lins: $[$fun1+$fun2]"
[root@wen-7 shell]# cat filist.sh | tr -s "\n"
#!/bin/bash
echo "通过命令传递两个文本,计算空白行之和"
[ $# -lt 2 ] && echo "2 ge canshu" && exit 1
fuo1=$(grep "^$" $1|wc -l)
fun2=$(grep "^$" $2|wc -l)
echo "tolal blank lins: $[$fun1+$fun2]"
#tr

10、将文件中每个单词(字母)显示在独立的一行,并无空行

[root@wen-7 shell]# cat filist.sh | tr -s "\040" "\n"
#!/bin/bash
echo
"通过命令传递两个文本,计算空白行之和"
[
$#
-lt
2
]
&&
echo
"2
ge
canshu"
&&
exit
1