bash Unix:如何将输出添加到文件中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7807004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unix: How can I prepend output to a file?
提问by Henrik
Specifically, I'm using a combination of >>and teein a custom alias to store new Homebrew updates in a text file, as well as output on screen:
具体来说,我使用的组合>>,并tee在自定义的别名存储在屏幕上的一个文本文件中新家酿的更新,以及输出:
alias bu="echo `date "+%Y-%m-%d at %H:%M"` \
>> ~/Documents/Homebrew\ Updates.txt && \
brew update | tee -a ~/Documents/Homebrew\ Updates.txt"
Question: What if I wish to prependthis output in my textfile, i.e. placed at the beginning of the file as opposed to appending it to the end?
问:如果我想在前面加上这个输出在我的文本文件,即放置在文件的开头,而不是将其附加到最后?
Edit1: As someone reported in the answers below, the use of temp files might be a good approach, which at least helped me partially:
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)"
But the problem is the output to STDOUT (previously made possible by tee), which I'm not sure can be incorporated in this tempfile approach …?
但问题是 STDOUT 的输出(以前由 tee 实现),我不确定是否可以将其合并到这种临时文件方法中……?
回答by Hasturkun
sed will happily do that for you, using -ito edit in place, eg.
sed 会很乐意为您做到这一点,用于-i就地编辑,例如。
sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
回答by mimoralea
This works by creating an output file:
这通过创建一个输出文件来工作:
Let's say we have the initial contents on file.txt
假设我们有 file.txt 的初始内容
echo "first line" > file.txt
echo "second line" >> file.txt
So, file.txt is our 'bottom' text file. Now prepend into a new 'output' file
所以,file.txt 是我们的“底部”文本文件。现在添加到一个新的“输出”文件中
echo "add new first line" | cat - file.txt > output.txt # <--- Just this command
Now, output has the contents the way we want. If you need your old name:
现在,输出具有我们想要的内容。如果您需要旧名称:
mv output.txt file.txt
cat file.txt
回答by Peter.O
The only simple and safeway to modify an input file using bash tools, is to use a temp file, eg. sed -iuses a temp file behind the scenes (but to be robust sedneeds more).
使用 bash 工具修改输入文件的唯一简单且安全的方法是使用临时文件,例如。sed -i在幕后使用临时文件(但要健壮sed需要更多)。
Some of the methods used have a subtle "can break things" trap, when, rather than running your command on the realdata file, you run it on a symbolic link(to the file you intend to modify). Unless catered for correctly, this can break the link and convert it into a realfile which receives the mods and leaves the originalreal file without the intended mods and without the symlink (no error exit-code results)
使用的一些方法有一个微妙的“可能会破坏事物”的陷阱,当您不是在真实数据文件上运行命令时,而是在符号链接(指向您打算修改的文件)上运行它。除非正确处理,否则这可能会破坏链接并将其转换为真实文件,该文件接收 mods 并保留原始真实文件而没有预期的 mods 和符号链接(没有错误退出代码结果)
To avoid this with sed, you need to use the --follow-symlinksoption.
For other methods, just be aware that it needs to follow symlinks (when you act on such a link)
Using a temp file, then rm temp fileworks only if "file" is not a symlink.
为了避免这种情况sed,您需要使用该--follow-symlinks选项。
对于其他方法,请注意它需要遵循符号链接(当您对此类链接执行操作时)
使用临时文件,然后rm temp file仅当“文件”不是符号链接时才有效。
One safe way is to use spongefrom package moreutils
一种安全的方法是使用spongefrom package moreutils
Unlike a shell redirect, sponge soaks up all its input before opening the output file. This allows for constructing pipelines that read from and write to the same file.
与 shell 重定向不同,海绵在打开输出文件之前吸收所有输入。这允许构建读取和写入同一文件的管道。
spongeis a good general way to handle this type of situation.
sponge是处理这种情况的一种很好的通用方法。
Here is an example, using sponge
这是一个例子,使用 sponge
hbu=~/'Documents/Homebrew Updates.txt'
{ date "+%Y-%m-%d at %H:%M"; cat "$hbu"; } | sponge "$hbu"
回答by J V
Simplest way IMO would be to use echo and cat:
IMO 最简单的方法是使用 echo 和 cat:
echo "Prepend" | cat - inputfile > outputfile
Or for your example basically replace the tee -a ~/Documents/Homebrew\ Updates.txtwith cat - ~/Documents/Homebrew\ Updates.txt > ~/Documents/Homebrew\ Updates.txt
或者你的榜样基本上替换tee -a ~/Documents/Homebrew\ Updates.txt用cat - ~/Documents/Homebrew\ Updates.txt > ~/Documents/Homebrew\ Updates.txt
Edit: As stated by hasturkun this won't work, try:
编辑:正如 hasturkun 所说,这行不通,请尝试:
echo "Prepend" | cat - file | tee file
But this isn't the most efficient way of doing it any more...
但这不再是最有效的方法了......
回答by SidJ
Try this http://www.unix.com/shell-programming-scripting/42200-add-text-beginning-file.htmlThere is no direct operator or command AFAIK.You use echo, cat, and mv to get the effect.
试试这个http://www.unix.com/shell-programming-scripting/42200-add-text-beginning-file.html没有直接的操作符或命令 AFAIK。你使用 echo、cat 和 mv 来获得效果.
回答by Mark Edgar
{ date; brew update |tee /dev/tty; cat updates.txt; } >updates.txt.new
mv updates.txt.new updates.txt
I've no idea why you want to do this. It's pretty standard that logs like this have later entries appearing, well, later in the file.
我不知道你为什么要这样做。像这样的日志在文件中稍后出现条目是非常标准的。

