本篇博文依然涉及到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