重定向和管道

输入和输出

程序是由指令加数据组成的,一般情况下都会有输入(Input)和输出(Output),当你由程序打开一个文件的时候就会产生一个文件描述符(file descriptor)。在Linux中有三种IO设备,分别是:

stdin:标准输入,默认情况下接受来自键盘的输入
stdpout:标准输出,默认情况下输出到终端的窗口
stderr:错误输出,默认情况输出终端的窗口

重定向

在默认情况下,stdout和stderr都是被输出到终端的,但是有时候,我们需要将其输出到指定的终端或者指定的文件记录下来,所有就有了重定向的概念

输出重定向

重定向符号 若文件不存在 若文件存在
> 创建,并将正确的输出写入到文件中 将正确的内容覆盖至目标文件
>> 创建,并将正确输出写入到文件中 将正确的内容追加至目标文件
2> 创建,并将错误输出写到文件中 将错误的内容覆盖至目标文件
2>> 创建,并将错误输出写到文件中 将错误的内容追加至目标文件
&> 创建,并将所有输出写到文件中 将所有的内容覆盖至目标文件
&>> 创建,并将所有输出写到文件中 将所有的内容追加至目标文件

在使用>>的时候,可能不小心就敲成>,就会造成有些重要数据的被覆盖从而丢失,这时候就可以通过set -C来禁止内容覆盖,因为系统默认是set +C允许覆盖,还可以使用>|来强制覆盖

[root@centos6 app]# echo nihao > nihao.txt
[root@centos6 app]# cat nihao.txt 
nihao
[root@centos6 app]# set -C
[root@centos6 app]# echo hello > nihao.txt 
-bash: nihao.txt: cannot overwrite existing file
[root@centos6 app]# echo hello >| nihao.txt 
[root@centos6 app]# cat nihao.txt 
hello

标准输出和错误输出可以重定向至不同的位置

[fanjie@centos6 ~]$ find /etc/ -name "*.conf" > /app/a.out 2> /app/b.err

可以使用()合并多个命令执行的结果到一个文件中

[root@centos6 app]# (cat /etc/passwd;cat /etc/shadow) > /app/etc.txt

正确输出和错误输出之间的相互切换

使用2>&1将错误结果转换正确结果

[fanjie@centos6 app]$ cat find.out |wc -l
406
[fanjie@centos6 app]$ find /etc/ -name "*.conf" > find.out 2>&1
[fanjie@centos6 app]$ cat find.out |wc -l
420

使用1>&2将正确结果转换错误结果

[fanjie@centos6 app]$ cat find.out |wc -l
14
[fanjie@centos6 app]$ find /etc/ -name "*.conf" 2> find.out 1>&
2
[fanjie@centos6 app]$ cat find.out |wc -l
420

以上两种方法其实和下面的方式的输出结果是一样的,这里使用的是&>

[fanjie@centos6 app]$ find /etc/ -name "*.conf" &> find.out
[fanjie@centos6 app]$ cat find.out |wc -l
420

输入重定向

从文件中导入到stdin

使用<来重定向标准输入,下面的例子就是将/etc/default/useradd的内容全部转换成大写

[root@centos6 app]# tr 'a-z' 'A-Z' < /etc/default/useradd 
# USERADD DEFAULTS FILE
GROUP=100
HOME=/HOME
INACTIVE=-1
EXPIRE=
SHELL=/BIN/BASH
SKEL=/ETC/SKEL
CREATE_MAIL_SPOOL=YES

比如现在我们想把/etc/fstab里面的abc中的任意字符删掉

[root@centos6 app]# tr -d "abc" < /etc/fstab

可以使用cat新建一个文件,然后键入内容,输入完成用Ctrl + d来完成

[root@centos6 app]# cat > test.txt
nihao
hello
[root@centos6 app]# cat test.txt 
nihao
hello

也可以将文件的内容输入到另一个文件,相当于是复制了一个文件

[root@centos6 app]# echo nihao > 1.txt
[root@centos6 app]# cat 1.txt 
nihao
[root@centos6 app]# cat >2.txt < 1.txt 
[root@centos6 app]# cat 2.txt 
nihao

多行发送给stdin

[root@centos6 app]# cat > file << EOF
> nihao 
> hello
> EOF
[root@centos6 app]# cat file
nihao 
hello

垃圾桶

当有的输出结果我们不需要时,就可以将其输出到/dev/null下

tr

转换和删除字符,常用选项:

  • -t:将第一个字符集对应的字符转换为第二个字符集对应的字符,默认
  • -d:删除所有第一字符集的字符
  • -s:把连续重复的字符以单独一个字符表示
  • -c:取字符集的补集
[root@centos6 app]# echo abcabc |tr ab x
xxcxxc
[root@centos6 app]# echo 1234567890 |tr 123 abcdef
abc4567890

[root@centos6 app]# echo aaabcbbbde |tr -s ab x
xcxde
[root@centos6 app]# echo aaabcbbbde |tr -s ab
abcbde

[root@centos6 app]# cat -A tr.txt 
abcabc$
[root@centos6 app]# cat tr.txt |tr -c ab x
abxabxx[root@centos6 app]# 

管道

管道是用来连接命令的,将前面命令的正确输出给后面命令的标准输入。stderr默认不能通过管道转发,可以利用2>&1或者是|&实现

[root@centos7 app]$ find /etc/ -name "*.conf" 2>&1  |wc -l
344
[root@centos7 app]$ find /etc/ -name "*.conf" |& wc -l
344

less

可以用man下的快捷键操作,相当于把输出结果放在man下查看

tee

重定向到多个目标,把/etc/default/useradd的内容转换成大写保存一份,然后在终端输出结果

[root@centos6 app]# cat /etc/default/useradd |tee useradd.txt |tr a-z A-Z
# USERADD DEFAULTS FILE
GROUP=100
HOME=/HOME
INACTIVE=-1
EXPIRE=
SHELL=/BIN/BASH
SKEL=/ETC/SKEL
CREATE_MAIL_SPOOL=YES

[root@centos6 app]# cat useradd.txt 
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

练习

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

    [root@centos6 app]# cat /etc/issue |tr a-z A-Z > /app/issue.out
    
  2. 将当前系统登录用户的信息转换为大写后保存至/app/who.out文件中

    [root@centos6 app]# who am i |tr a-z A-Z > /app/who.out
    
  3. 一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:
    Hello, I am 用户名,The system version is here,please help me to check it thanks!
    操作系统版本信息

    [fanjie@centos7 ~]$ mail -s "help" root <
  4. 将/root/下文件列表,显示成一行,并文件名之间用空格隔开

    [root@centos6 app]# ls /root/ |tr [:space:] ' '
    anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public Templates tr Videos 
    [root@centos6 app]# ls /root/ |tr '\n' ' '
    anaconda-ks.cfg Desktop Documents Downloads install.log install.log.syslog Music Pictures Public Templates tr Videos 
    
  5. 计算1+2+3+..+99+100的总和

    [root@centos6 app]# echo {1..100} |tr [:blank:] + |bc
    5050
    [root@centos6 app]# echo {1..100} |tr ' ' + |bc
    5050
    
  6. 删除Windows文本文件中的‘^M’字符

    [root@centos6 app]# cat windows.txt |tr -d '\r' |cat -A
    a$
    b$
    c$
    d$
    e$
    
  7. 处理字符串“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4”,只保留其中的数字和空格

    [root@centos6 app]# echo xt.,l 1 jr#-Amn 2 c*/fe 3 uz 4 |tr -d [:alpha:][:punct:]
     1  2  3  4
    [root@centos6 app]# echo xt.,l 1 jr#-Amn 2 c*/fe 3 uz 4 |tr -cd [:digit:][:blank:]
     1  2  3  4
    
  8. 将PATH变量每个目录显示在独立的一行

    [root@centos6 app]# echo $PATH |tr : '\n'
    
  9. 将指定文件中0-9分别替代成a-j

    [root@centos6 app]# echo 9876543210 |tr 0-9 a-j
    jihgfedcba
    
  10. 将文件中每个单词(由字母组成)显示在独立的一行,并无空行

    [root@centos6 app]# echo nihao hello fanjie |tr [:blank:] '\n'
    

你可能感兴趣的:(重定向和管道)