3.重定向与管道
前言
不知道大家上节课那些命令掌握的怎么样,这些命令一定要自己亲自去敲一遍才能加深印象,不用死记硬背,用的次数多了自然就记住了
本节用到的命令
wc命令
wc命令,全称是word count
,并不是你们想的那样,主要用于计算文件的字节数、单词数、或是列数
wc [options] [name...]
参数 | 含义 |
---|---|
-c | 字节数 |
-l | 行数 |
-w | 单词数(这里的单词是英文意义上的,以空白隔开) |
sort命令
sort命令,顾名思义就是用于排序的命令,主要可针对文本文件的内容,以行为单位来排序
sort [options] name
参数 | 含义 |
---|---|
-b | 忽略每行前面开始出的空格字符 |
-f | 忽略大小写 |
-t split | 指定排序时所用的栏位分隔字符,split为分隔字符 |
-n | 依照数值的大小排序 |
-r | 以相反的顺序来排序 |
-k field1 [fieldN...] | 按指定的列进行排序,field为列 |
-o output | 将排序后的结果存入指定的文件,output为文件名 |
举例说明:
创建一个score.txt
文件内容如下,假设是学生的成绩
xiaomi 60
laowang 78
zhangsan 90
Lisi 56
wangwu 89
Zhaoliu 100
tianqi 30
按学生名字顺序输出
sort -f score.txt
按学生成绩倒序输出
sort -nrk2 score.txt
grep命令
为了方便我们后面的演示,这里学一个比较重要的命令grep
,它与sed
及awk
被称为Linux文本处理三剑客,后面会详细介绍另外两个
grep命令能够在一个或多个文件中,搜索某一特定的字符模式(也就是正则表达式),此模式可以是单一的字符、字符串、单词或句子
正则表达式:描述一组字符串的一个模式,正则表达式的构成模仿了数学表达式,通过使用操作符将较小的表达式组合成一个新的表达式,这个学过一些编程语言的朋友们应该或多或少都有了解,这里就只做简单说明,如果感兴趣可以看看菜鸟教程里的相关介绍:正则表达式 - 教程
通配符 | 含义 |
---|---|
* | 将匹配 0 个(即空白)或多个字符前面出现的字符 |
. | 将匹配任何一个字符,且只能是一个字符 |
[abc] | 匹配方括号中的任意一个字符,括号内为做任意数量的任意字符 |
[^abc] | 匹配除方括号中字符外的所有字符,括号内为做任意数量的任意字符 |
^ | 以后面的字符开头 |
$ | 以前面的字符结尾 |
grep [options] keyword name... #keyword为正则表达式,name为文件名
参数 | 含义 |
---|---|
-c | 仅列出文件中包含keyword的行数 |
-i | 忽略模式中的字母大小写 |
-l | 列出带有匹配行的文件名 |
-n | 在每一行的最前面列出行号 |
-v | 列出没有匹配模式的行 |
-r | 递归查找 |
我们以/etc/passwd
文件为例对该命令做一个简单的认识
例1:查找文件中包含me的行
grep 'me' /etc/passwd
例2:在上述的的基础上输出行号
grep -n 'me' /etc/passwd
例3:列出共有多少行以s开头n结尾的行数
grep -c '^s.*n$' /etc/passwd
例4:列出/etc目录下以s开头n结尾的文件及行号,并忽略错误输出
grep -nr '^s.*n$' /etc/* 2>/dev/null
重定向
基本概念介绍
在Liunx shell
中,重定向为意思为改变标准输入输出的方向,重定向分为两种,输入重定向和输出重定向,这么说可能有些抽象,先看一些概念
-
什么是输入输出方向
- 输入方向:数据从哪里流向程序
- 输出方向:数据从程序流向哪里
-
什么是标准的输入入输出方向
- 标准输入方向:数据默认的输入方向为从键盘流向程序
- 标准输出方向:数据默认的输出方向为从程序流向显示器
-
什么是输入输出重定向
- 输入重定向:改变了数据的标准输入方向,即数据从其它地方流入程序
- 输出重定向:改变了数据的标准输出方向,即数据从程序流入其它地方
看完这些概念大家是不是已经蒙了,这个没关系,后面会有例子帮大家理清这些的
文件描述符
在Linux中,一切皆文件,包括标准输入设备(键盘)和标准输出设备(显示器)在内的所有计算机硬件都是文件,为了区分这些打开的文件,Linux会为每个文件有一个整数做标识,这个整数就被称为文件描述符(File Descriptor),相当于一个非负的文件索引,我们可以通过文件描述符操作相应的文件
在LLinux进程中,会默认打开三个文件描述符
文件描述符 | 文件名 | 类型 | 硬件 |
---|---|---|---|
0 | /dev/stdin | 标准输入文件 | 键盘 |
1 | /dev/stdout | 标准输出文件 | 显示器 |
2 | /dev/stderr | 标准错误输出文件 | 显示器 |
一般来说,我们打开文件后占用一个文件描述符,由于0、1、2已被标准文件描述符占用,他就可以往后找一个没有被占用的文件描述符来占用
大家知道有这么个东西就行了,这个用的不多,就知道我上面例出的三个的意思就行,如果大家想要深入了解这块内容,大家可以看看CSDN上的这篇帖子彻底弄懂 Linux 下的文件描述符(fd)
输出重定向
输出重定向是指命令的结果不再输出到显示器上,而是输出到如文件中。这样做的最大好处就是把程序的输出结果保存起来,当我们需要的时候可以随时查询
在Linux中有如下的输出重定向符号
命令 | 说明 |
---|---|
command >file | 以覆盖的方式,把 command 的正确输出结果输出到 file 文件中 |
command >>file | 以追加的方式,把 command 的正确输出结果输出到 file 文件中 |
command n>file | 以覆盖的方式,把文件描述符为 n 的文件重定向到 file文件中 |
command n>>file | 以追加的方式,把文件描述符为 n 的文件重定向到 file文件中 |
command >file n>&m | 以覆盖的方式,把文件描述符为n与文件描述符为m的输出合并到file文件中 |
当描述符为1时可以不写,默认就是1
例1:标准输出
把/etc下的文件详情输出到桌面的demo1.txt中
ls -l /etc 1> ~/Desktop/demo1.txt
ls -l /etc > ~/Desktop/demo1.txt
例2:错误输出
把错误输出重定向到桌面的err.txt中
命令正确执行是没有错误信息的,我们必须刻意地让命令执行出错
ls abcd.aaa 2>err.txt
例3:综合练习
执行下面的程序完成相关操作
在桌面创建名为output.sh
的文件,内容如下:
#!/bin/bash
while :
do
username=`cat /proc/sys/kernel/random/uuid | md5sum |cut -c 1-9`
path=`cat /proc/sys/kernel/random/uuid | md5sum |cut -c 1-9`
echo `date` "user [$username] view file: $path"
ls $path
sleep 1
done
在桌面执行如下命令:
chmod +x output.sh
运行文件可以查看效果
将正常输出保留在屏幕,错误输出到桌面的err.log
的文件中
./output.sh 2>err.log
将错误输出保留在屏幕,正常输出到out.log
的文件中
./output.sh 1>out.log
将错误输出到err.log
文件中,正常输出到out.log
的文件中
./output.sh 1>out.log 2>err.log
将错误输出与正常输出合并输出到application.log
文件中
./output.sh >application.log 2>&1 # 把标准输出重定向到application.log的文件中,然后把错误输出合并到标准输出中
/dev/null 文件
上节课我们讲过,/dev
目录是存在设备的特殊目录,这个目录下有个null
设备,即为一个空白设备,有时我们不想把信息输出到屏幕,也不想输出到文件,就可以重定向到此,断续以上面的程序举例
./output.sh >/dev/null 2>&1
输入重定向
与输出重定向类似,输入重定向是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件
在Linux中有如下的输入重定向符号
命令 | 说明 |
---|---|
command <file | 将 file 文件中的内容作为 command 的输入 |
command <<END | 从标准输入(键盘)中读取数据,直到遇见分界符 END 才停止(分界符可以是任意的字符串,用户自己定义,常见的有EOF:end of file) |
例1:统计标准输入的信息
我们可以把标准输入作为wc命令的输入来计统计我们从键盘字符的信息
wc <<EOF
123456
hello world
i amd lengwen
kevinlu98.cn
EOF
例2:将用户的输入输出到文件
我们希望将我们的输入直接输出到文件中,这样可以方便快捷的创建文件
cat <<EOF>file.txt
hello
i amd lengwen
my site is kevinlu98.cn
EOF
管道
Linux除了有上面的输入输出重定向,还有一种功能,就是可以将两个或者多个命令(程序或者进程)连接到一起,把一个命令的输出作为下一个命令的输入,以这种方式连接的两个或者多个命令就形成了管道(pipeline)
Linux 管道使用竖线|
连接多个命令,这被称为管道符
command1 | command2
command1 | command2 [|commandN...]
当在两个命令之间设置管道时,管道符|
左边命令的输出就变成了右边命令的输入。只要第一个命令向标准输出写入,而第二个命令是从标准输入读取,那么这两个命令就可以形成一个管道,这里需要注意,command2 必须可以处理 command1 的输出结果
管道也是一种文件,管道中的读数据是一次性操作,数据一旦被读,它就从管道中被抛弃
例1:查找文件是否在目录内
查找passwd是否在/etc目录下
ls /etc/ | grep 'passwd'
列出当前目录下.bashrc的详细信息
ls -a | grep 'passwd'
例2:按文件大小顺序输出
我们先列出文件的详细信息,文件的大小在第5列,然后用数值方式对其逆向输出
ls -l | sort -nrk5
小结
这节课我们主要讲了重定向及管道,这两个都是改变文件的输出,不同的是重定向是连接命令的输出与文件,而管道是连接命令与命令的,这两个知识点在日常工作中用到的频率还是非常高的,希望大家可以好好理解一下,自己多动手写一写,想一些需求自己做一做