『Linux学习笔记』7. 管道和过滤器 -- pipe

摘要:
在Linux中,一个管道可以将一个命令的标准输出发送到另一命令的标准输入。多个管道可以形成一个管道。管道运算符类似于重定向。管道也有自己的运算符“|”。当多个命令与“|”连接时,这意味着它们位于同一管道中。它们的标准输出和标准输入将依次连接。ls | less,ls获取的当前目录内容将被传递到less中打开,而不是直接发送到标准输出(屏幕)文本过滤命令。在使用中,管道

在Linux中, 管道(pipe)可以将一个命令的标准输出送往另一个命令的标准输入, 多个管道可以组成管道线(pipeline).

管道操作符

与重定向类似, 管道也拥有自己的操作符"|", 当多个命令使用"|"连接时, 就意味着它们位于同一管道中, 它们的标准输出与标准输入会依次相连.

ls | less

上面这行代码中, ls所获取的当前目录内容将被传入less打开而非直接送往标准输出(屏幕)

文本过滤命令

在使用中, 管道通常会将多个指令连接在一起以完成复杂的操作, 而过程中不乏对文本数据进行操作的指令, 如筛选查重统计分割等, 而这类命令就是"文本过滤命令"或被称为"过滤器".

下面将依次介绍常用的过滤器并举例说明:

grep

grep是常用的筛选命令之一, 它可以在输入数据中匹配关键字. 若成功匹配, 它将会高亮显示成功的匹配关键字并输出关键字所在的行.

grep keyword [file...]

上方keyword指需要匹配的关键字, file指grep的输入, 若file不指定则为系统标准输入(键盘); 若grep在管道中, 则grep的输入为上一命令的标准输出.

下面将通过两组指令来帮助建立管道和grep的概念:

ls -a ~ | grep bash

再与下述指令的执行结果对比一下:

ls -a ~

经过上面的例子不难发现, 第一组指令中的"ls -a"指令的标准输出没有被送到系统默认的标准输出上(屏幕), 而是通过管道送往了下一指令grep的标准输入中, 最终标准输出(屏幕)得到的结果则是"grep"在当前目录下匹配到"bash"关键词的所有行;

uniq

当我们获得了大量数据时, 有时会希望找出或过滤掉重复的内容, 这时就需要用到uniq命令.

与其他过滤器相似, uniq也常被用在管道线中;

在默认状态下, uniq会删除所有重复的行, 像这样:

ls -a ~ | uniq

上述命令将会输出所有在当前用户的home目录下的非重复文件或文件夹.

有时, 我们不希望重复的内容被删除, 而是希望将其标注出来, 那么可以选择在使用uniq时加上-d参数

ls -a ~ | uniq -d

这样, 重复的行将会被高亮显示而非直接移除.

sort

我们手上的数据并非总是有序的, 这时就需要使用sort命令对数据进行排序.

如我们使用ls命令同时获取多个目录下的文件时, 我们拿到的文件名将会使未经排序的:

cd ~
ls /bin /usr/bin

此时, 如果使用sort并将其放入管道

cd ~
ls /bin /usr/bin | sort

我们将得到经过排序后的文件名.

PS: 由于uniq命令需要接收有序数据, 因此通常sort与uniq会结合使用:

cd ~
ls /bin /usr/bin | sort | uniq

wc

wc命令源于word count的单词首字母, 其意为字数统计, 但实际上wc能做的远不止如此.

拿上一章所创建的文件举例, 如果我们要统计output.txt文件中的字符数据, 可以这样使用:

wc output.txt

此时, wc命令所输出的内容包括3组使用空格分割的数字以及目标文件名, 它们分别代表 行数 单词数 字节数.

同样的, 如果我们不为wc指定输入, 那么它将从标准输入(键盘)中获取数据.

如果我们只希望统计数据中的行数, 那么可以使用-l参数

cd ~
ls /bin /usr/bin | sort | uniq | wc -l

这样, 我们就得到了bin和usr/bin目录下所有的非重复文件(文件夹)计数.

head 和 tail

有时我们并不需要查看一个命令的所有输出, 可能我们只想要前几行或末尾几行的内容, 这时就可以使用head和tail命令;

在默认情况下, head会打印前10行数据, tail则会打印末尾10行数据. 并且它们提供了一个"-n"参数以供显式指定打印的行数;

它们同样可以被用在管道线中:

head -n 15 output.txt | grep a

这样, 我们会获得output.txt的前15行中带有字符"a"的行.

此外, tail命令还提供了"-f"参数以供我们选择是否实时更新内容, 如果在调用时使用-f参数, 那么每当目标更新, tail就将立刻反映到输出上. 这在查看日志文件时比较常用:

tail -f /var/log/messages

tee

如果在管道线的其中某一步我们希望取得当前步骤的输入输出时, Shell为我们提供了tee命令, 它会从标准输入中取得数据, 并将其复制到标准输出.

文字上可能难以描述tee所存在的意义, 但代码可以:

ls ~ | tee home_ls.txt | grep pdf

通过执行上述代码, 我们将得到一个home_ls.txt文件夹, 内容为home目录下所有文件(ls的执行结果), 并且, 我们会在终端上得到home目录下所有文件名带有"pdf"的文件.

通过上面的例子不难认识到, tee的存在使管道线执行过程中数据的I/O操作成为了可能, 相信在今后的使用中也会逐渐认识到它的作用.

免责声明:文章转载自《『Linux学习笔记』7. 管道和过滤器 -- pipe》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇redis的LRU算法(一)积木大赛 2013年NOIP全国联赛提高组下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

配置zabbix当内存剩余不足15%的时候触发报警

zabbix默认的剩余内存报警:Average Lack of available memory on server {HOST.NAME}{Template OS Linux:vm.memory.size[available].last(0)}<20M这个值配置的过小,每台机器的内存也不一样。 1.创建item Configuration-->...

Linux 搭建 Jenkins

环境准备 安装JDK 安装 JDK 之前写过一篇文章,本文就不具体讲了: Linux 安装 JDK 注意:Java版本不能是gcj,会导致Jenkins有问题,centos7搭建jenkins小记文章中提到的java版本问题导致CentOS下的Jenkins有问题。 安装Git yum install git 规避磁盘过满问题 1.方法1:创建软连接,准...

Linux命令行下批量重命名文件名为数字索引编号(0~N.xxx)的方法

在处理一些数据集的时候,我们经常会碰到数据集的文件名是按时间戳(time stamp),或者其他方式命名的文件,如: 12345679.jpg, sunshine.txt 而我们在编写程序时,往往希望读入的这些数据集的文件名是一种更简洁的形式,比如按照索引(index)方式:1.png,2.png,3.png...,那么如何批量重命名一个文件夹下的文件名呢...

【网易云音乐 for linux】 踩过的坑

1.从官网下载的包,却怎么也安装不上。 提示依赖,网上全是什么 sudo apt-get -f install ,结果提示有没有完成安装的包,让我卸载。 于是按下Y卸载了网易云。 尝试一个个修复以来,却提示不行。 。。。一段时间之后。。。 2.下载了网易云音乐1.0,提示的以来不一样了 于是一个个修复依赖,但是最后一个无法修复:libqt5libqgtk2...

Linux平台Java调用so库JNI使用例子

1.确保gcc编译器已安装 2.编写HelloJNI.java代码,用native声明需要用C实现的函数。 如果源程序是包含在package里的话,应该建立同样的文件夹结构,比如/home/swan/test/net/wangliping/HelloJNI.java   package net.wanglipingpublic class Hello...

OS + Linux sshkeygen / sshcopyid / id_rsa / id_rsa.pub / authorized_keys

s Ansible自动部署lnmp架构+上线电商 https://www.cnblogs.com/Zrecret/p/12072289.html ssh-keygen和ssh-copy-id实现免密登录远程主机 https://blog.csdn.net/feinifi/article/details/78213297 Linux上用ssh-keygen和...