四、IO重定向和管道以及基本文本处理工具
一、三种IO设备
程序:数据+指令 或 数据结构+算法
程序必须能够读入输入然后经过加工来产生结果,其接受的输入可以是变量、数组、列表、文件等等,生产出来的结果可以使变量、数组、列表、文件等等。即:
程序都有读入数据和输出数据的需求
读入数据:input
输出数据:output
一、标准文件描述符
linux系统将每个对象当作文件处理,这包括输入和输出进程。linux用文件描述符(file descriptor)来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件。每个进程一次最多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符(0,1和2)
Linux给程序提供三种IO设备:
- 标准输入(STDIN)-0 默认接受来自键盘的输入
- 标准输出(STDOUT)-1 默认输出到终端窗口
- 标准错误(STDERR)-2 默认输出到终端窗口
在Linux中,一切皆文件,我们每打开文件,系统都会自动分配一个FD(file description,文件描述符)。上面的0,1,2就是系统分配的文件描述符。
ll /proc/$$/fd 查看目前的文件描述符
exec <>/data/hosts
表示给/data/hosts文件指定一个文件描述符8,且8与/data/hosts之间是软链接
exec >&- 删除8号这个文件描述符
二、IO重定向:改变默认位置
1、>标准的输出重定向:
ls > /dev/pts/5 命令ls重定向输出至窗口5
ls > /data/ls.out 命令ls重定向输出至/data/ls.out文件中
注意:假如ls.out文件中本来就有内容,那么重定向输出后会覆盖文件中原有的内容
2、>>:追加重定向,新内容会追加至目标文件尾部
ls >> /data/ls.out
3、():合并多个程序的STDOUT
(cal 2007;cal 2008) > all.txt
4、2>标准错误的输出重定向:
cmd 2> /data/err.log cmd(本身无cmd这个命令,所以输入此命令会显示错误的结果)的错误结果重新定向显示至 data/err.log 中
注意:history 2> /data/err.log 由于本身history命令是正确的,所以默认的输出设备会正常显示history命令的内容,且不会输出至/data/err.log中。原data/err.log中的文件会被空文件覆盖。
cmd 2>> /data/err.log 这样就会将正确的信息显示在默认的输出设备上,而且每次的错误信息输入至err.log文件中,方便后面研究问题
对于输出既有正确信息又有错误信息的场景:
ls /err /data >f1 >f2 则正确信息输出至f1 中,错误信息输出至f2 中
ls /err /data &>all.log 正确信息和错误信息都输出至all.log文件中。
或
ls /err /data >all.log >&1 #把错的当成对的
ls /err /data >all.log >& 注意次序!!
- 注意区分以下几项,哪个与众不同:
cmd > log >&
cmd >& >log 此项与众不同
cmd &> log
cmd >log >&
set –C 禁止将内容覆盖已有文件,但可追加
>| file 强制覆盖
set +C 允许覆盖
TIPS:
小技巧:> bigfile效果是创建了一个bigfile的空文件。背后的原理是利用重定向标准输出的原理,重定向输出至bigfile文件,由于无任何输出结果,所以直接效果就是创建了一个空的bigfile文件。所以一个比较安全的创建空文件的方法是:\>> file .
原因:1. 假如file文件原来就存在,那么>> 不会覆盖原来的文件,只会在原文件基础上累加。
2.>> 不会刷新时间,touch命令会刷新时间
*** 非常重要: 假如 abc_link -> abc (abc_link软链接abc),
那么我们> abc_link 的话,会直接覆盖源文件abc !!!!
5、 < 标准输入重定向
cat < file file文件内容输入到cat命令上
cat < f1 > f2 f2里显示f1 内容的文件
cat < f1 > f1 清空f1 文件
cat < f1 >>f2 无限循环将f1文件累加至f2文件
二、tr命令(删除和转换字符)
tr [OPTION]... SET1 [SET2]
Translate, squeeze, and/or delete characters from standard input, writing to standard output.
tr 'a-z' 'A-Z' #将输入的任意小写字符转换为大写,其他的字符保持原样
tr -c,–C --complement:#use the complement of SET1;取字符集的补集;
tr -d,--delete: #delete characters in SET1, do not translate;删除所有属于第一字符集的字符
tr -s,--squeeze-repeats:#replace each input sequence of a repeated character that is listed in SET1 with a single occurrence of that character;把连续重复的字符以单独一个字符表示
tr -t,--truncate-set1:#first truncate SET1 to length of SET2;将第一个字符集对应字符转化为第二字符集
tr 'a-z' 'A-Z' < /etc/fstab :将/etc/fstab这个文件中的小写字符转换为大写字符
tr –d abc < /etc/fstab 删除/etc/fstab这个文件中的abc字符
实验1:将df命令显示输出里的连续空格全部以一个空格输出
第一步:df > /data/test.out 将df命令的输出结果定向至/data/test.out文件中。
第二步:tr -s ' ' < /data/test.out 完成
把多行发送给STDIN
使用“<<终止词”命令从键盘把多行重导向给STDIN
mail -s "PleaseCall" admin@magedu.com << END >HiWang,
>
>Pleasegivemeacallwhenyougetin.Wemayneed
>todosomemaintenanceonserver1.
>
>Detailswhenyou’reon-site
>Zhang
>END
用END终止多行输入,并将内容以邮件方式发送给admin@magedu.com,邮件主题为PleaseCall
三、管道
less :一页一页地查看输入 ls -l /etc | less mail :通过电子邮件发送输入 echo "test email" | mail -s "test" user @example.com lpr:把输入发送给打印机 echo "test print" | lpr -p printer_name
管道(使用符号“|”表示)用来连接命令
命令1 | 命令2 | 命令3 | …
- 将命令1的STDOUT发送给命令2的STDIN,命令2的STDOUT发送到命令3的STDIN
- STDERR默认不能通过管道转发,可利用2>&1 或|& 实现
ls /data /err >& | tr 'a-z' 'A-Z'
ls /data /err |& tr 'a-z' 'A-Z'
实验1: 随机产生的16位字符串,将其中的小写字符换成大写字符,并且删除无用的字符。
第一步:
openssl rand -base64 16 > /data/test.out 随机产生16位的字符串。并将其定向输出至文件中。
第二步:
tr -dc '[:alpha:]' < /data/test.out | tr 'a-z' 'A-Z' 删除非字母的字符并将小写转换为大写
实验2: 计算1+2+3+4+…+100 =
echo {1..100} | tr ' ' '+' | bc
seq -s + 1 100 | bc
管道中"-"符号
示例:
将/home 里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout,经过管道后,将tar -cvf-/home 传送给后面的tar -xvf-, 后面的这个-则是取前一个命令的stdout,因此,就不需要使用临时file了
tar -cvf-/home | tar -xvf-
四、tee,重定向到多个目标
tee - read from standard input and write to standard output and files
tee [OPTION]... [FILE]...
命令1 | tee [-a ] 文件名| 命令2
把命令1的STDOUT保存在文件中,同时做为命令2的输入,
tee -a, --append #append to the given FILEs, do not overwrite,追加输出至文件中
使用场景:
- 保存不同阶段的输出
- 复杂管道的故障排除
- 同时查看和记录输出
五、几个文本查看工具:wc, cut, sort, uniq, diff, patch
1.wc:word count
wc - print newline, word, and byte counts for each file
wc [OPTION]... [FILE]...
~]# wc anaconda-ks.cfg
anaconda-ks.cfg
# :表示行数
# :表示字数
# :字节数 # option
-l:只计数行数
-w:只计算单词总数
-c:只计数字节总数
-m:只计数字符总数
2.cut:remove sections from each line of files
cut OPTION... [FILE]...
# option:
-d --delimiter=DELIM : 指明分隔符,默认tab
-f --fields=LIST :
# :指定第#个字段
#-#:指定第#-#个字段;如3-,第3-5个字段
#,#:指定离散的多个字段;如3,,
#,#-#:
3.sort:sort lines of text files
把整理过的文本显示在STDOUT,不改变原始文件
sort [OPTION]... [FILE]...
# option:
-n:基于数值大小而非字符进行排序;
-r:逆序排序;
-f:忽略字符大小写
-t CHAR:指定分隔符; (类似cut的-d命令)
-k #:用于排序比较的字段;(类似cut -f 命令)
-u:连续且相同的重复的行只保留一行;
4.uniq:report or omit repeated lines
报告或移除重复的行
uniq [OPTION]... [INPUT [OUTPUT]]
# option
-c:显示每行的重复次数;
-u:仅显示未曾重复过的行;
-d:仅显示重复过的的行; # 常和sort一起使用:
sort userlist.txt | uniq-c
5.diff、patch
diff - compare files line by line
patch - apply changes to files
diff [OPTION]... FILES
diff /PATH/TO/OLDFILE /PATH/TO/NEWFILE > /PATH/TO/PATCH_FILE
-u:使用unfied机制,即显示要修改的行的上下文,默认为3行,适用于补丁文件; ###
patch:复制在其它文件中进行的改变(要谨慎使用),即向文件打补丁;
patch [OPTIONS] -i /PATH/TO/PATCH_FILE /PATH/TO/OLDFILE
patch /PATH/TO/OLDFILE < /PATH/TO/PATCH_FILE
-b:自动备份改变了的文件
6.cat、tac、rev
cat - concatenate files and print on the standard output
cat [OPTION]... [FILE]...
# option:
-E: 显示行结束符$
-n: 对显示出的每一行进行编号
-A:显示所有控制符
-s:压缩连续的空行成一行 ###
tac - concatenate and print files in reverse (反向显示cat的输出结果)
tac [OPTION]... [FILE]... ###
rev - reverse lines of a file or files
rev [options] [file ...]
7.more、less
分页查看文件内容
8.head、tail
head - output the first part of files 默认显示前10行
tail - output the last part of files 默认显示后10行
head [OPTION]... [FILE]...
# option:
-n #: 指定获取前#行
-c #: 指定获取前#字节
-#:指定行数 ###
tail [OPTION]... [FILE]...
# option:
-n #: 指定获取后#行
-c #: 指定获取后#字节
-#:指定行数
-f: 跟踪显示文件fd新追加的内容,常用日志监控;相当于--follow=descriptor
-F: 跟踪文件名,相当于—follow=name --retry
要获取/etc/passwd文件, 要获取其第6-10行,并显示每行的行号
# ). -n显示行号,tail -n +6显示第6行之后的行,结合head -n ,获取前面5行,刚好6-
$ cat -n /etc/passwd | tail -n + | head -n # ). 先用head -n 10来获取前10行,再结合tail -n 5获取后面5行,刚好也是6-10行
$ cat -n /etc/passwd | head -n | tail -n |sort -n -k3 |cut -d: -f1 # ). cat -n来显示行号,再用awk中$1来判断行号范围
$ cat -n /etc/passwd | awk '($1 > 1 && $1 < 11){print $0}'
# ). 借助于6,10p来打印第6行到第10行
$ cat -n /etc/passwd | sed -n '6,10p' # ). =打印行号,使用N;来获取下一行,再用\t来替换换行符,最后使用6,10p来获取
$ sed = /etc/passwd | sed 'N;s/\n/\t/' | sed -n '6,10p'
六、练习
1、将/etc/issue文件中的内容转换为大写后保存至/tmp/issue.out文件中
tr 'a-z' 'A-Z' < /etc/issue | tee -a /data/issue.out
2、将当前系统登录用户的信息转换为大写后保存至/tmp/who.out文件中
who | tr 'a-z' 'A-Z' > /data/who.out
3、一个linux用户给root发邮件,要求邮件标题为”help”,邮件正文如下:
Hello, I am 用户名,The system version is here,pleasehelp me to check it ,thanks!
操作系统版本信息
4、将/root/下文件列表,显示成一行,并文件名之间用空格隔开
ls /root | tr '\n' ' '
5、计算1+2+3+…+99+100的总和
echo {1..100} | tr ' ' '+' | bc
6、处理字符串“xt.,l 1 jr#!$mn2 c*/fe3 uz4”,只保留其中的数字和空格
tr -dc [0-9][:space:]
7、将PATH变量每个目录显示在独立的一行
echo $PATH | tr ':' '\n'
8、将指定文件中0-9分别替代成a-j
tr '0-9' 'a-j' < 文件
四、IO重定向和管道以及基本文本处理工具的更多相关文章
- IO重定向与管道
一.三种IO设备 程序:数据+指令 或 数据结构+算法 程序必须能够读入输入然后经过加工来产生结果,其接受的输入可以是变量.数组.列表.文件等等,生产出来的结果可以使变量.数组.列表.文件等等.即: ...
- Linux IO重定向和管道
计算机组成部分: 由io . 控制器.计算器.存储器组成 IO: input output 计算机里面通过终端窗口实现输入和输出,键盘鼠标屏幕这些只是手段,真正完成输入输出的是终端窗口 标准输入.出. ...
- linux学习14 Linux运维高级系统应用-glob通配及IO重定向
一.回顾 1.bash基础特性:命令补全,路径补全,命令引用 2.文件或目录的复制,移动及删除操作 3.变量:变量类型 存储格式,数据表示范围,参与运算 二.bash的基础特性 1.globbing: ...
- linux初级学习笔记九:linux I/O管理,重定向及管道!(视频序号:04_3)
本节学习的命令:tr,tee,wc 本节学习的技能: 计算机的组成 I/O管理及重定向 管道的使用 知识点九:管理及IO重定向(4_3) 计算机组成: 运算器.控制器: CPU 存储器:RAM ...
- Linux Shell 重定向与管道【转帖】
by 程默 在了解重定向之前,我们先来看看linux 的文件描述符. linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以 ...
- Bash : IO 重定向
标准输入/输出(standard I/O)可能是软件设计原则里最重要的概念了.这个概念就是:程序应该有数据的来源端.数据的目的端(输出结果的地方)已经报告问题的地方,它们分别被称为标准输入(stand ...
- Linux-IO重定向与管道
1. 输入与输出 标准输入 STDIN 文件描述符:0,默认:键盘输入 标准输出 STDOUT 文件描述符:1,默认:屏幕输出 错误输出 STDERR 文件描述符:2,默认:屏幕输出 2. 标准输出重 ...
- I/O重定向和管道
一:I/O设备 I/O(Input/Output),即输入/输出,通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出. 标准输入(STDIN):0 默认接受来自键盘的输入 标准输出(ST ...
- shell IO重定向
I/O重定向 默认情况下,有3个"文件"处于打开状态,stdin,stdout,stderr:重定向的解释:捕捉一个文件,命令,程序,脚本或者脚本中的代码块的输出,然后将这些输出作 ...
随机推荐
- ThreadLocal使用场景,原理
ThreadLocal 1. 先说下 ThreadLocal不能解决多线程间共享数据,他是一个隔离多线程间共享数据的好帮手 2. ThreadLocal是本地线程共享数据 3. 他是以空间换时间 sy ...
- Python字符串常用的方法——真心觉得比java,c好用
# Strings have many methods wo can use rand_string=" life is a beautiful struggle " print( ...
- makemigrations和migrate到底干了什么以及如何查询原生的sql语句
在你改动了 model.py的内容之后执行下面的命令: python manger.py makemigrations 相当于 在该app下建立 migrations目录,并记录下你所有的关于mode ...
- C#应用笔记
1.ref关键字.out关键字——引用传递参数 2.什么时候用DateReader,什么时候用DateSet呢? 3.is操作符.as操作符的使用 4.Eval方法和Bind方法的区别 5.Serve ...
- 怎么解决64位Access与32位不能同时安装的问题
如何在同时安装32位和64位Micsoft Access数据库引擎 由于某些64位应用程序需要访问Access数据库,而访问数据库须使用AccessDataEngine即Access数据库引擎64 ...
- OpenCl入门——实现简单卷积
现在的卷积实现无非是那么几种:直接卷积.im2col+gemm.局部gemm.wingrod.FFT.如果直接卷积的话,其实kernel函数是比较好实现.以下代码参考至<OpenCL Progr ...
- 如何查找SAP Fiori launchpad Designer的准确路径即url地址
比如我们知道在SPRO里下面这个路径的customizing activity里打开Fiori Launchpad designer: SAP Netweaver->UI technologie ...
- linux物理地址和虚拟地址
- 04_Redis_Hash命令
一:Redis 哈希(Hash) 1.1:Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. 1.2:Redis 中每个 hash 可以存储 ...
- CentOs Linux 对于编辑文本内容时无法退出的几个小命令
编辑完保存退出的四种方式 1. Esc+:+wq+回车(w是write,q是quit) 2. Esc+:+x+回车(x=wq) 3. Esc+shift+zz 4. Esc+ZZ(在大写开启下)