Unix:如何将输出附加到文件中?

s5a0g9ez  于 2022-11-04  发布在  Unix
关注(0)|答案(6)|浏览(234)

具体来说,我在一个自定义别名中使用>>tee的组合,将新的Homebrew更新存储在一个文本文件中,并在屏幕上输出:

alias bu="echo `date "+%Y-%m-%d at %H:%M"` \
    >> ~/Documents/Homebrew\ Updates.txt && \
    brew update | tee -a ~/Documents/Homebrew\ Updates.txt"

问题:如果我想在我的文本文件中 prepend 这个输出,也就是说,放在文件的开头,而不是把它附加到结尾,该怎么办?
Edit1:正如有人在下面的回答中所报告的,使用临时文件可能是一个很好的方法,这至少对我有部分帮助:

targetLog="~/Documents/Homebrew\ Updates.txt"
alias bu="(brew update | cat - $targetLog \
> /tmp/out1 && mv /tmp/out1 $targetLog \
&& echo `date "+%Y-%m-%d at %H:%M":%S` | \
cat - $targetLog > /tmp/out2 \
&& mv /tmp/out2 $targetLog)"

但问题是输出到STDOUT(以前由tee实现),我不确定是否可以将其合并到这个临时文件方法中...?

rqcrx0a6

rqcrx0a61#

sed会很乐意为你做这件事,使用-i在适当的地方编辑,例如。

sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
hjzp0vay

hjzp0vay2#

其工作原理是创建一个输出文件:
假设我们在file.txt上有初始内容

echo "first line" > file.txt          
echo "second line" >> file.txt

因此,file.txt是我们的“底层”文本文件。现在,将其添加到一个新的“输出”文件中

echo "add new first line" | cat - file.txt > output.txt # <--- Just this command

现在,输出的内容符合我们的要求。如果需要旧名称:

mv output.txt file.txt
cat file.txt
mzmfm0qo

mzmfm0qo3#

使用bash工具修改输入文件的唯一简单和 * 安全 * 的方法是使用一个临时文件,例如sed -i在后台使用一个临时文件(但为了更强大,sed需要更多)。
使用的一些方法有一个微妙的“可以破坏东西”陷阱,当你不是在 * 真实的 * 数据文件上运行你的命令,而是在 symbolic link 上运行它时(添加到您要修改的文件)。除非正确地满足了要求,这可以断开链接并将其转换为一个 * 真实的 * 文件,该文件接收mods并留下没有预期mods和符号链接的 * 原始 * real文件(没有错误退出代码结果)
为了避免sed出现这种情况,需要使用--follow-symlinks选项。
对于其他方法,只需注意它需要遵循符号链接(当您对这样的链接进行操作时)
如果使用临时文件,那么rm temp file只有在“file”不是符号链接时才起作用。
一种安全的方法是使用包 moreutils 中的sponge
与shell重定向不同的是,sponge在打开输出文件之前吸收了所有的输入,这允许构建从同一个文件读取和写入的管道。
sponge是处理这种情况的一种很好的通用方法。
下面是一个示例,使用sponge

hbu=~/'Documents/Homebrew Updates.txt'
{ date "+%Y-%m-%d at %H:%M"; cat "$hbu"; } | sponge "$hbu"
gwo2fgha

gwo2fgha4#

IMO最简单的方法是使用echo和cat:

echo "Prepend" | cat - inputfile > outputfile

或者,对于您的示例,基本上将tee -a ~/Documents/Homebrew\ Updates.txt替换为cat - ~/Documents/Homebrew\ Updates.txt > ~/Documents/Homebrew\ Updates.txt
编辑:正如hasturkun所说,这行不通,试试看:

echo "Prepend" | cat - file | tee file

但这已经不是最有效的方法了...

oxf4rvwz

oxf4rvwz5#

这里没有直接的操作符或命令AFAIK。你使用echo,cat和mv来获得效果。

noj0wjuj

noj0wjuj6#

{ date; brew update |tee /dev/tty; cat updates.txt; } >updates.txt.new
mv updates.txt.new updates.txt

我不知道你为什么要这样做。像这样的日志在文件的后面出现条目是很正常的。

相关问题