内容来自实验楼
stdio
对于 Linux 内核中的标准 I/O 库 stdio 提供了一个高效的缓存 I/O 流接口。
一般情况下,每个程序在启动时都会有三个 stream(流)在启动时被预定义,一个用于输入,一个用于输出,还有一个用于打印诊断或者错误信息。
对于 linux 系统中来说,读取标准输入和打印标准输出的地方默认情况下都是所使用的终端。对应 shell 中常使用的三种标准 I/O 流:
stdinstdoutstderr
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 程序和命令之间的通信。 在 shell 中,管道符(pipeline)是 shell 编程中众多控制操作符其中的一个,用来分隔一个或多个命令的序列。shell 编程中管道符号是竖杠符号 |(但是有时会使用到 |& 符号,该用法将在后面的内容中详细描述)
在 shell 中使用管道的格式如下,代表着 command1 的标准输出作为 command2 的标准输入使用,而 command2 的标准输出又作为 command3 的标准输入使用:
1 | command1 | command2 | command3 |
简单示例,匹配字符串 shiyanlou:
1 | $ echo "shiyanlou001" | grep "shiyanlou" |
重定向
在执行命令之前,我们可以使用 shell 解释的特殊符号重定其输入和输出。
重定向输入
重定向输入的一般格式为:
1 | [n] < file |
这里代表的意思是将输入从文件描述符为 n 的文件重定向到 file。
不指定 n 时,文件描述符 n 为 0,为标准输入。代表着将输入从标准输入重定向到 file 中。
重定向输出
重定向输出的一般格式为:
1 | [n] > file |
这里代表的意思是将输出从文件描述符为 n 的文件重定向到 file。
不指定 n 时,文件描述符 n 为 1,为标准输出。代表着将输出从标准输出重定向到 file 中。
这里需要注意的是,如果 file 不存在,将会创建 file,如果 file 存在,文件大小将被设为 0,然后输出,即覆盖原有文件的内容。如果需要将输出内容附加到文件中,需要使用 >> 来替代 > 符号。
如下,命令示例说明,及运行截图。
1 | $ ls |
重定向 stdout 和 stderr
首先,我们回顾一下,管道符部分提到的 |& 符号,使用的格式如下:
1 | command1 |& command2 |
代表着将 command1 命令的标准输出和标准错误作为 command2 的标准输入。不同于 |,这里多了一个标准错误的选项。
如下示例,我们查看一个当前目录下不存在的文件 test4。将给出的错误信息重定向到 test5中:
1 | $ ls test4 |
上述方式是使用管道符的方式,在这里,我们还可以使用重定向的方式来达到相同的效果。重定向标准输出和标准错误的格式如下:
1 | &> file |
对于第一种方式,在语义上等同于 >file 2>&1。意思是将标准错误(文件描述符为 2) 重定向到标准输出(文件描述符为 1),然后将标准输出重定向到 file。
对于附加 stdout 和 stderr ,使用如下的格式:
1 | &>>file |
更常用的一种用法是将标准输入和标准错误分别重定向到两个文件,例如 command 2>err.log 1>info.log 这个命令表示 err.log 和 info.log 分别用来存储 command 命令的标准错误和标准输出。
tee
tee 命令用于读取标准输入,并将其写入到标准输出和文件中。
tee 命令的格式为:
1 | tee [option].. [file]... |
常用参数有:
-a或--append附加到已有文件内容的后面,而不是覆盖。-i忽略中断信号
如下示例:
1 | $ tee test1 test2 |
退出 tee 用 Ctrl+d。
还可以在终端打印 stdout 同时重定向到文件中。
1 | $ ls | tee out.txt |
文本处理
对于保存文本文件时,我们可以按照一定的结构去保存文本内容。类似于我们常使用的表。
例如,如下为 test1 的文本内容保存着实验楼的账号信息,分别为 ID,性别,年龄,并且由空格分隔
1 | shiyanlou200 man 30 |
排序
sort 命令可用于将文本内容以行为单位进行排序。
关于 sort 命令的详细用法可以使用 sort --help 查看,这里我们简单介绍一些常用的参数。
-u去除重复行-t指定分隔字符,例如上面我们使用的空格字符,默认为空格-o输出到指定文件-k指定使用某一列进行排序-r修改默认的升序排序为降序
如下,我们使用 test1 中的年龄进行排序,并保存到 test2 中。
1 | $ cat test1 |
合并
paste 命令可以将多个文件以列对列的方式加以合并。
如下示例:
1 | $ cat num2 |
join 命令则可以将多个文件中有相同特征的行以类似于 paste 的方式进行组合。
如下示例:
1 | $ cat file1 |
tr
Linux tr 命令将标准输入复制到标准输出,在这个过程中可以执行转译或删除操作。
tr 命令的格式如下:
1 | tr [option] set1 [set2] |
set1 代表需要转换的或删除的原字符集。set2 为转换的目标字符集。例如,我们将打印到标准输入的 shiyanlou 的小写字母全部转换为大写字母:
1 | $ echo "shiyanlou" | tr a-z A-Z |
在上面的示例中 a-z 和 A-Z 都是属于集合,分别代表所有的小写字母和所有的大写字母。集合通常可以自己定义。需要注意的是,这里的字符集并不是正则表达式,只是字符列表。
例如,m-n 代表从 m 到 n 的所有的字符,按升序排序, 0-9 代表的是字符集合 0123456789
xargs
xargs 命令可以从标准输入构建和执行命令。
xargs 常用来给其他命令传递参数,从标准输入读取数据,默认情况下使用空格或者换行符作为默认定界符,忽略空白行,并且在没有指定命令的时候,默认将数据传递给 /bin/echo ,即我们常用的 echo 命令作为参数。例如:
1 | # 使用 tail 命令查看 /etc/hosts 的后五行 |
运行结果如下所示,使用 xargs 后换行和空白都被一个空格所取代,即使用命令行参数的标准格式:
下面我们将介绍一些常用的参数
-a使用该参数指定从文件中读取,而不是标准输入。-d自定义定界符-n每行的最多参数个数
简单示例,自定义定界符为字符 x ,并且设定每行参数的最大参数个数为 2:
1 | $ echo "shiyanlou001xshiyanlou002xshiyanlou003" | xargs -n 2 -d x |