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

发布于 2024-12-10 10:22:56 字数 796 浏览 0 评论 0原文

具体来说,我在自定义别名中使用 >>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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

难理解 2024-12-17 10:22:56

sed 会很乐意为您做到这一点,使用 -i 进行就地编辑,例如。

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

sed will happily do that for you, using -i to edit in place, eg.

sed -i -e "1i `date "+%Y-%m-%d at %H:%M"`" some_file
方圜几里 2024-12-17 10:22:56

这是通过创建一个输出文件来实现的:

假设我们在 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

This works by creating an output file:

Let's say we have the initial contents on 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

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
戏舞 2024-12-17 10:22:56

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

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

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

一种安全的方法是使用包 moreutilssponge >

与 shell 重定向不同,海绵会先吸收所有输入
开幕
输出文件。这允许构建读取的管道
并写入同一个文件。

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

这是一个使用 sponge 的示例

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

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 robust sed 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 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.

sponge is a good general way to handle this type of situation.

Here is an example, using sponge

hbu=~/'Documents/Homebrew Updates.txt'
{ date "+%Y-%m-%d at %H:%M"; cat "$hbu"; } | sponge "$hbu"
噩梦成真你也成魔 2024-12-17 10:22:56

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

但这不再是最有效的方法......

Simplest way IMO would be to use echo and cat:

echo "Prepend" | cat - inputfile > outputfile

Or for your example basically replace the tee -a ~/Documents/Homebrew\ Updates.txt with cat - ~/Documents/Homebrew\ Updates.txt > ~/Documents/Homebrew\ Updates.txt

Edit: As stated by hasturkun this won't work, try:

echo "Prepend" | cat - file | tee file

But this isn't the most efficient way of doing it any more...

秋叶绚丽 2024-12-17 10:22:56

与接受的答案类似,但是如果您来到这里是因为您想在第一行前面添加 - 而不是在前面添加一个全新的行 - 那么请使用此命令。

sed -i "1 s/^/string_replacement/" some_file

-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.

sed -i "1 s/^/string_replacement/" some_file

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 syntax s/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.

荒岛晴空 2024-12-17 10:22:56

试试这个 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.

最美的太阳 2024-12-17 10:22:56
{ date; brew update |tee /dev/tty; cat updates.txt; } >updates.txt.new
mv updates.txt.new updates.txt

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

{ 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文