使用终端输出的内容命名文件

使用终端输出的内容命名文件

此主题这里讨论了如何将终端内容输出到文件。具体来说,使用这个:

command |& tee output.txt

问题:能否利用输出内容的一部分来命名文件。例如,假设内容逐行打印如下:

action_1_last_time_2021_06_15_21_34_56
action_2_last_time_2021_06_15_21_35_23
action_3_last_time_2021_06_15_21_43_45
...
action_320032_last_time_2021_06_15_23_59_14

是否可以使用最后一行的内容来命名文件,而不是out.txt在命令行上命名?也许是某种变量?这里,最后一行被假定定义为在文件关闭(并且命令完成运行)之前出现的行。

答案1

不管你如何解决这个问题,你都必须缓冲命令输出,直到你可以读取最后一行,才能知道在哪里写入它。

我能想到的唯一合理方法是使用临时文件,然后重命名它:

tmpfile=$(mktemp)
outfile=$(command | tee "$tmpfile" | tail -n 1)
mv "$tmpfile" "$outfile"

如果你真的想捕获 stdout 和 stderr,你可以更改|为- 但请注意,这|&可能导致以错误消息命名输出文件(尽管可能有办法使用巧妙的文件描述符 fu 来避免这种情况)。

也许可以使用sponge命令(来自包moreutils)来实现替代解决方案,但这可能使用相同的技术。事实上,手册页说

   When possible, sponge creates or updates the output file atomically by
   renaming a temp file into place.

另一个选项可能是使用rev反转行,以便您可以先读取最后一行,然后rev再次恢复输出顺序。但是,这涉及缓冲整个输出两次

相关内容