Unix:如何将输出添加到文件中?
具体来说,我在自定义别名中使用 >>
和 tee
的组合,将新的 Homebrew 更新存储在文本文件中,并在屏幕上输出:
alias bu="echo `date "+%Y-%m-%d at %H:%M"` \
>> ~/Documents/Homebrew\ Updates.txt && \
brew update | tee -a ~/Documents/Homebrew\ Updates.txt"
问题:如果我希望将此输出添加到文本文件中(即放置在文件的开头而不是附加到末尾),该怎么办?
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 实现) ,我不确定是否可以将其合并到此临时文件方法中……?
Specifically, I'm using a combination of >>
and tee
in a custom alias to store new Homebrew updates in a text file, as well as output on screen:
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 prepend this 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:
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 …?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
sed 会很乐意为您做到这一点,使用
-i
进行就地编辑,例如。sed will happily do that for you, using
-i
to edit in place, eg.这是通过创建一个输出文件来实现的:
假设我们在 file.txt 上有初始内容
,那么 file.txt 是我们的“底部”文本文件。现在添加到一个新的“输出”文件中
现在,输出具有我们想要的内容。如果您需要旧名字:
This works by creating an output file:
Let's say we have the initial contents on file.txt
So, file.txt is our 'bottom' text file. Now prepend into a new 'output' file
Now, output has the contents the way we want. If you need your old name:
使用 bash 工具修改输入文件的唯一简单且安全的方法是使用临时文件,例如。
sed -i
在幕后使用临时文件(但为了稳健,sed
需要更多)。使用的某些方法有一个微妙的“可能破坏事物”陷阱,当您不是在真实数据文件上运行命令时,而是在符号链接上运行命令(到您要修改的文件)。除非正确处理,否则这可能会破坏链接并将其转换为一个真实文件,该文件接收mods并留下原始真实文件,没有预期的mods并且没有符号链接(没有错误退出代码结果)
要使用
sed
避免这种情况,您需要使用--follow-symlinks
选项。对于其他方法,请注意它需要遵循符号链接(当您对此类链接进行操作时)
使用临时文件,则仅当“file”不是符号链接时,
rm temp file
才有效。一种安全的方法是使用包 moreutilssponge >
sponge
是处理此类情况的一种很好的通用方法。这是一个使用
sponge
的示例The only simple and safe way to modify an input file using bash tools, is to use a temp file, eg.
sed -i
uses a temp file behind the scenes (but to be robustsed
needs more).Some of the methods used have a subtle "can break things" trap, when, rather than running your command on the real data 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 real file which receives the mods and leaves the original real file without the intended mods and without the symlink (no error exit-code results)
To avoid this with
sed
, you need to use the--follow-symlinks
option.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 file
works only if "file" is not a symlink.One safe way is to use
sponge
from package moreutilssponge
is a good general way to handle this type of situation.Here is an example, using
sponge
IMO最简单的方法是使用 echo 和 cat:
或者对于您的示例,基本上将
tee -a ~/Documents/Homebrew\ Updates.txt
替换为cat - ~/Documents/Homebrew\ Updates .txt> ~/Documents/Homebrew\ Updates.txt
编辑:正如 hasturkun 所说,这不起作用,尝试:
但这不再是最有效的方法......
Simplest way IMO would be to use echo and cat:
Or for your example basically replace the
tee -a ~/Documents/Homebrew\ Updates.txt
withcat - ~/Documents/Homebrew\ Updates.txt > ~/Documents/Homebrew\ Updates.txt
Edit: As stated by hasturkun this won't work, try:
But this isn't the most efficient way of doing it any more...
与接受的答案类似,但是如果您来到这里是因为您想在第一行前面添加 - 而不是在前面添加一个全新的行 - 那么请使用此命令。
-i
标志将在文件内进行替换(而不是创建新文件)。那么
1
只会在第 1 行进行替换。最后,使用
s
命令,其语法如下s/find/replacement/flags.
在我们的例子中,我们不需要任何标志。
^
称为脱字符号,用于表示字符串的开头。Similar to the accepted answer, however if you are coming here because you want to prepend to the first line - rather than prepend an entirely new line - then use this command.
The
-i
flag will do a replacement within the file (rather than creating a new file).Then the
1
will only do the replacement on line 1.Finally, the
s
command is used which has the following syntaxs/find/replacement/flags
.In our case we don't need any flags. The
^
is called a caret and it is used to represent the very start of a string.试试这个 http://www.unix.com /shell-programming-scripting/42200-add-text-beginning-file.html
没有直接的操作符或命令 AFAIK。您使用 echo、cat 和 mv 来获得效果。
Try this http://www.unix.com/shell-programming-scripting/42200-add-text-beginning-file.html
There is no direct operator or command AFAIK.You use echo, cat, and mv to get the effect.
我不知道你为什么要这样做。像这样的日志后面的条目会出现在文件的后面,这是非常标准的。
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.