使用 bash 编写 Unix 过滤器

Uwe*_*der 3 bash

如果 Unix/Linux 命令接受来自标准输入的输入数据并在标准输出上产生其输出(结果),则称为过滤器。

微不足道的过滤器是cat。它只是将 stdin 复制到 stdout 而不做任何修改。

我如何cat在 bash 中实现?(忽略命令获取命令行参数的情况)

我想出了

#! /bin/bash

while IFS="" read -r line
do
  echo -E "$line"
done
Run Code Online (Sandbox Code Playgroud)

这似乎在大多数情况下都有效,也适用于包含一些二进制字节的文本文件,只要它们不是空字节。但是,如果最后一行不是以换行符结尾,则输出中将缺少该行。

如何解决?

我几乎可以肯定之前肯定已经回答过这个问题,但是我的搜索技巧似乎还不够好。

显然我不想cat在 bash 中重新实现:由于空字节问题,它无论如何都不起作用。但我想扩展基本循环以对文本文件的某些行进行一些自定义处理。但是,我们都见过没有最后换行符的文本文件,所以我更希望这种情况能得到处理。

che*_*ner 5

假设您不需要使用任意二进制文件(因为 shell 无法在变量中存储空字节),您可以通过检查line循环退出后是否不为空来处理未由换行符终止的文件。

while IFS= read -r line; do
    printf '%s\n' "$line"
done
if [ -n "$line" ]; then
    printf '%s' "$line"
fi
Run Code Online (Sandbox Code Playgroud)

循环中,我们输出read剥离的换行符。在 final 中if,我们不输出换行符,因为$line如果while循环读取的最后一行以 1 结尾,则该换行符将为空。