简体   繁体   English

将python脚本的输出重定向到文件的开始

[英]Redirect the output of a python script to THE BEGINNING of a file

I am aware of the following options to append the output to a file: 我知道以下将输出附加到文件的选项:

test.py: test.py:

print "Error"
print "Warning"

test.txt: 的test.txt:

Levels:
Debug

When I do: 当我做:

python test.py > test.txt

It appends at the end of the file. 它附加在文件末尾。

However, if I want to append at the beginning of a file, so that the output of my file looks like as follows: 但是,如果我想在文件的开头追加内容,则文件的输出如下所示:

Levels:
Error
Warning
Debug

Is there any straightforward way of doing this possibly without manually creating a temporary file (sed -i is OK for example). 是否有任何简单的方法可以执行此操作而无需手动创建临时文件(例如sed -i是可以的)。

I have tried several sed approach: 我尝试了几种sed方法:

sed -i '1i\`python test.py`' test.txt

But none seems to be working. 但是似乎没有一个工作。

An easy way to do this is to use a separate, temporary file: 一种简单的方法是使用单独的临时文件:

python test.py | cat - test.txt > tmp && mv tmp test.txt

The - means that cat uses standard input. -表示cat使用标准输入。


I just realised that you actually want to put the text after the first line, not right at the beginning. 我只是意识到您实际上是想将文本放在第一行之后,而不是放在开头。 To do this, you could use awk: 为此,您可以使用awk:

python test.py | awk 'NR==FNR{a[++n]=$0;next}1;/Levels:/{for(i=1;i<=n;++i)print a[i]}' - test.txt

NR is the overall record (line) number and FNR is the record number of the current input. NR是总记录(行)号, FNR是当前输入的记录号。 NR==FNR means that the first block only operates on the first input (which in this case is the output of your python script). NR==FNR表示第一个块仅在第一个输入上操作(在这种情况下,这是python脚本的输出)。 The output is added to a buffer a . 输出将添加到缓冲区a The next means that awk skips the rest of the commands and goes to the next line. next意味着awk跳过其余命令并转到下一行。

1 is a shorthand which causes all of the lines in the file to be printed. 1是使文件中所有行都被打印的简写。 When the line containing "Levels:" is found, each line of the buffer a is also printed. 当找到包含“ Levels:”的行时,缓冲区a每一行也会被打印。

You can use the same trick as above to write the output to a temporary file, then overwrite the original file. 您可以使用与上述相同的技巧将输出写入临时文件,然后覆盖原始文件。

This should do it: 应该这样做:

python test.py |
awk '
    NR==FNR { a[NR] = $0; next }
    { print (FNR==1 ? a[1] RS : "") $0 }
    END { for (i=2;i in a;i++) print a[i] > ARGV[1] }
' test.txt -

The above reads the first file into an array, then closes that file before opening the stdin stream coming from the pipe so from then on it can safely overwrite the first file with it's original contents from the array merged with the input from the pipe in whatever order you like. 上面的代码将第一个文件读入数组,然后在打开来自管道的stdin流之前关闭该文件,因此从那时起,它可以安全地覆盖数组中原始内容与管道输入合并后的第一个文件订购你喜欢的。

Unlike awk '...' file > file , this is perfectly safe to do since it's awk rather than the shell deciding when to overwrite the file, it's only issue would be memory usage and speed if the original file is huge. awk '...' file > file ,这是完全安全的,因为它是awk而不是shell决定何时覆盖文件,如果原始文件很大,唯一的问题就是内存使用率和速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM