除了使用临时文件来提供帮助之外,是否有一种方法/程序可以缓冲输入stdin
但在获取EOF
.我也不想使用 shell 变量(例如buffer=$(cat)
)。
该程序应如下所示(假设程序名称为buffered-cat
):
$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)
现在程序收到了^D
,buffered-cat
输出内容
line 1
line 2
line 3
答案1
你可以这样做sponge
来自 moreutils。sponge
将“吸收标准输入并写入文件”。如果没有参数,该文件是标准输出。该命令的输入将存储在内存中直到 EOF,然后一次性全部写出。
要写入普通文件,您只需给出文件名即可:
cmd | sponge filename
的主要目的sponge
是允许在管道中读取和写入同一文件,但它也可以满足您的要求。
答案2
一个穷人正在sponge
使用awk
:
awk '{a[NR] = $0} END {for (i = 1; i <= NR; i++) print a[i]}'
如果你有tac
,你也可以滥用它:
... | tac | tac
答案3
只要您的输入是 ASCII 文本(直到结束为止不包含 NUL 0x0 字节),然后sed -z
执行您想要的操作:
$ sed -z ''
Line 1
Line 2
Line 3
^D
Line 1
Line 2
Line 3
$
-z
将sed
NUL 字节视为行分隔符而不是通常的换行符的原因。因此,只要您的输入是没有 NUL 字节的常规文本,那么 sed 就会继续将整个输入读取到其模式缓冲区中,直到达到 EOF。 sed
然后不对缓冲区进行任何处理并输出它。
如果您的输入中存在 NUL 字节,那么您可以这样做:
sed ':l;N;bl'
答案4
与 muru 的 awk 示例的想法相同,但在 Python 中除外。用于CtrlD停止按行阅读
$ python -c 'import sys;print("".join(sys.stdin.readlines()))'
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3