Unix:如何将输出预先添加到文件中?

Hen*_*rik 13 unix bash redirect tee

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

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

:如果我想什么前面加上这个输出在我的文本文件,即放置在文件的开头,而不是将其附加到最后?


编辑1:正如有人在下面的答案中报告的那样,使用临时文件可能是一个很好的方法,这至少对我有所帮助:

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)"
Run Code Online (Sandbox Code Playgroud)

但问题是STDOUT的输出(之前由tee实现),我不确定是否可以将其纳入此tempfile方法......?

Has*_*kun 13

sed会很乐意为你做这件事,用来-i编辑,例如.

sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
Run Code Online (Sandbox Code Playgroud)

  • 至少在OSX上,sed需要一个-i参数.所以,让...`-i'' - e` ...... (5认同)

mim*_*lea 8

这通过创建输出文件来工作:

假设我们在file.txt上有初始内容

echo "first line" > file.txt          
echo "second line" >> file.txt
Run Code Online (Sandbox Code Playgroud)

因此,file.txt是我们的"底部"文本文件.现在预先添加到一个新的"输出"文件中

echo "add new first line" | cat - file.txt > output.txt # <--- Just this command
Run Code Online (Sandbox Code Playgroud)

现在,输出具有我们想要的内容.如果你需要你的旧名字:

mv output.txt file.txt
cat file.txt
Run Code Online (Sandbox Code Playgroud)


Pet*_*r.O 5

使用 bash 工具修改输入文件的唯一简单且安全的方法是使用临时文件,例如。sed -i在幕后使用临时文件(但要健壮sed需要更多)。

使用的一些方法有一个微妙的“可能会破坏事物”的陷阱,当您不是在真实数据文件上运行命令时,而是在符号链接(指向您打算修改的文件)上运行它。除非正确处理,否则这可能会破坏链接并将其转换为真实文件,该文件接收 mods 并保留原始真实文件而没有预期的 mods 和符号链接(没有错误退出代码结果)

为了避免这种情况sed,您需要使用该--follow-symlinks选项。
对于其他方法,请注意它需要遵循符号链接(当您对此类链接执行操作时)
使用临时文件,然后rm temp file仅当“文件”不是符号链接时才有效。

一种安全的方法是使用spongefrom package moreutils

与 shell 重定向不同,海绵在打开输出文件之前吸收所有输入。这允许构建从同一文件读取和写入的管道。

sponge 是处理这种情况的一种很好的通用方法。

这是一个例子,使用 sponge

hbu=~/'Documents/Homebrew Updates.txt'
{ date "+%Y-%m-%d at %H:%M"; cat "$hbu"; } | sponge "$hbu"
Run Code Online (Sandbox Code Playgroud)