Linux 管道符

王 茂南 2022年1月21日07:45:10
评论
2884字阅读9分36秒
摘要本文呢会介绍在 shell 编程中经常使用到的重定向的相关知识,以及文本处理的一些常用命令。本文主要有以下的内容,标准输入输出-stdio(包含三种 I/O 流);管道符的简单使用;重定向(重定向输入,重定向输出,重定向错误);简单的文本处理(「排序」与「合并」)和 xargs 命令。

简介

这篇文章将着重介绍在 shell 编程中经常使用到的重定向的相关知识,以及文本处理的一些常用命令。本文会分为以下几个内容进行介绍:

  • 标准输入输出-stdio(包含三种 I/O 流);
  • 管道符的简单使用;
  • 重定向(重定向输入,重定向输出,重定向错误);
  • 简单的文本处理(「排序」与「合并」);
  • xargs 命令(将字符串按指定符号进行分割);

 

标准输入输出-stdio

对于 Linux 内核中的标准 I/Ostdio 提供了一个高效的缓存 I/O 流接口。一般情况下,每个程序在启动时都会有三个 stream(流)在启动时被预定义,一个用于输入,一个用于输出,还有一个用于打印诊断或者错误信息。

对于 linux 系统中来说,读取标准输入和打印标准输出的地方默认情况下都是所使用的终端。对应 shell 中常使用的三种标准 I/O 流:

  • stdin,标准输入流;
  • stdout,标准输出流;
  • stderr,诊断错误信息流;

 

输入流-stdin

输入流(input stream)被称作标准输入(standard input),缩写形式即为 stdin。在程序启动时,与 stdin 关联的整数文件描述符为 0

这里我们引入文件描述符的概念(百度百科的定义):

  • 内核(kernel)利用文件描述符(file descriptor)来访问文件。
  • 文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
  • 实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

 

输出流-stdout

输出流(output stream)被称作标准输出(standard output),缩写形式即为 stdout。在程序启动时,与 stdout 关联的整数文件描述符为 1

 

错误流-stderr

错误流(error stream)被称作标准错误输出(standard error),缩写形式即为 stderr。在程序启动时,与 stderr 关联的整数文件描述符为 2

 

Linux 管道符

Linux 管道来说可以用于 Linux 程序之间,Linux 命令之间以及 Linux 程序和命令之间的通信。 在 shell 中,管道符(pipeline)是 shell 编程中众多控制操作符其中的一个,用来分隔一个或多个命令的序列。shell 编程中管道符号是竖杠符号 |(但是有时会使用到 |& 符号,这种用法会同时包含「输出流」和「错误流」,该用法将在后面的内容中详细描述)。

在 shell 中使用管道的格式如下,代表着 command1 的标准输出作为 command2 的标准输入使用,而 command2 的标准输出又作为 command3 的标准输入使用:

  1. command1 | command2 | command3

例如下面一个简单的例子。第一个命令使用 echo 来输出文字,第二个命令使用 grep 将第一个 echo 的输出当作输出:

Linux 管道符

 

重定向

在执行命令之前,我们可以使用 shell 解释的特殊符号重定其输入和输出。下面会分别来将「重定向输入」,「重定向输出」,

重定向输入

重定向输入的一般格式如下:

  1. [n] < file

上面命令代表的意思是将输入从文件描述符为 n 的文件重定向到 file。不指定 n 时,文件描述符 n 为 0,为标准输入。代表着将输入从标准输入重定向到 file 中(简单理解为,将文件 file 的内容作为输入)。

我们来看一个例子。首先新建一个文件,在其中写入 Happy New Year!。如下所示:

Linux 管道符

接着将该文件作为 grep 的输入,使用 grep 查找 Happy

Linux 管道符

 

重定向输出

重定向输出的格式如下所示:

  1. [n] > file

这里代表的意思是将输出从文件描述符为 n 的文件重定向到 file不指定 n 时,文件描述符 n 为 1,为标准输出。代表着将输出从标准输出重定向到 file 中。

这里需要注意的是,如果 file 不存在,将会创建 file,如果 file 存在,文件大小将被设为 0,然后输出,即覆盖原有文件的内容。如果需要将输出内容附加到文件中,需要使用 >> 来替代 > 符号。

我们来看一个例子。我们将 echo 的输出保存在文件 file1 中,然后查看文件内容:

Linux 管道符

 

重定向 stdout 和 stderr

这里我们会用到管道符部分提到的 |& 符号,使用的格式如下:

  1. command1 |& command2

上面的命令表示将 command1 命令的「标准输出」和「标准错误」作为 command2 的标准输入。不同于 |,这里多了一个标准错误的选项。

下面来看一个例子。我们查看当前目录下一个不存在的文件,这个时候会出现「标准错误」。我们使用 |& 符号将这个标准错误作为 cat 的输入,接着将 cat 的输出重定向到 file 文件

Linux 管道符

除此之外,还可以使用 &> 符号达到一样的效果。如下所示,将「标准错误」输出到 file 文件中:

Linux 管道符

更常用的一种用法是将「标准输入」和「标准错误」分别重定向到两个文件。例如 command 2>err.log 1>info.log 这个命令表示 err.log 和 info.log 分别用来存储 command 命令的标准错误和标准输出。下面是一个例子:

Linux 管道符

 

简单的文本处理

Linux 的一些命令支持对文件进行简单的操作。例如现在有一个文件,存储着个人信息(包含姓名和年龄),如下所示:

  1. name1 30
  2. name2 20
  3. name3 25

 

对文件进行排序

我们可以使用 sort 命令对文本内容进行排序。关于 sort 命令的详细用法可以使用 sort --help 查看,这里我们简单介绍一些常用的参数。

  • -u 去除重复行;
  • -t 指定分隔字符,例如上面我们使用的空格字符,默认为空格;
  • -o 输出到指定文件;
  • -k 指定使用某一列进行排序;
  • -r 修改默认的升序排序为降序;

例如我们对上面的文件,按照年龄进行降序排序,最终的结果如下所示:

Linux 管道符

 

对文件的合并

有两种文件合并的方式,分别是 pastejoin 的方式。

  • paste 命令可以将多个文件以列对列的方式加以合并;
  • join 命令可以将多个文件中有相同特征的列进行合并;

现在我们新建一个文件,里面包含每个学生和他的学号,如下所示:

  1. name1 man
  2. name2 woman
  3. name4 man

我们首先来看一下paste 命令的效果(可以看到只是单纯的合并):

Linux 管道符

如果这个时候我们使用join 命令,则会尝试进行合并(保留共有内容的行):

Linux 管道符

 

 

xargs 命令

xargs 命令可以从标准输入构建和执行命令。xargs 常用来给其他命令传递参数,从标准输入读取数据,默认情况下使用空格或者换行符作为默认定界符,忽略空白行,并且在没有指定命令的时候,默认将数据传递给 /bin/echo ,即我们常用的 echo 命令作为参数。下面我们将介绍一些常用的参数:

  • -a 使用该参数指定从文件中读取,而不是标准输入;
  • -d 自定义定界符;
  • -n 每行的最多参数个数;

例如下面的例子中,我们使用 x 作为「定界符」,每行显示一个,将原本一行的内容分开:

Linux 管道符

 

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2022年1月21日07:45:10
  • 转载请务必保留本文链接:https://mathpretty.com/14447.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: