Python 读取2个文件并在另一个文件中替换一个文件的某些值的脚本
以下是我努力实现的目标: 文件1包含如下内容:Python 读取2个文件并在另一个文件中替换一个文件的某些值的脚本,python,perl,Python,Perl,以下是我努力实现的目标: 文件1包含如下内容: . . . get_time file 10 -max 5 -min 0 abcde get_time file 9 -max 5 -min 0 abfdf get_time file 9 -max 5 -avg 3 -min 0 xyyxx get_time file 10 -max 5 -min 0 abcxx . . . 同时,文件2只包含: abcde 8 abfdf 8.5 xyyxx 7.5 abcxx 9
.
.
.
get_time file 10 -max 5 -min 0 abcde
get_time file 9 -max 5 -min 0 abfdf
get_time file 9 -max 5 -avg 3 -min 0 xyyxx
get_time file 10 -max 5 -min 0 abcxx
.
.
.
同时,文件2只包含:
abcde 8
abfdf 8.5
xyyxx 7.5
abcxx 9
.
.
.
我需要的是一个文件3,它精确地打印出文件1中的内容,只是相应地替换第3列中的值
因此,输出应该如下所示:
.
.
.
get_time file 8 -max 5 -min 0 abcde
get_time file 8.5 -max 5 -min 0 abfdf
get_time file 7.5 -max 5 -avg 3 -min 0 xyyxx
get_time file 9 -max 5 -min 0 abcxx
.
.
.
注意:文件1包含很多其他东西,在它之前和之后都不是以“get_time”开头的。在上面的例子中,它们被标记为点
谢谢你的帮助
编辑:谢谢!快速跟进。另一个类似的文件有如下内容:
get_time file123 tmp 10 -max 5 -min 0 abcde
get_time file foo 9 -max 5 -min 0 abfdf
get_time file43 bar 9 -max 5 -avg 3 -min 0 xyyxx
您将如何修改您的脚本?再次感谢将文件2读入哈希或字典,其中键是5个字母的标记 每次读取文件1一行,将第三列中的值替换为哈希或字典中基于行末尾出现的标记找到的值
Perl 文件2 输出 我想我应该发布一个最高级的Perl解决方案 如果这些行中的任何一行需要执行替换,脚本必须知道如何找到需要替换(或不需要替换)的数字。可能将替换行更改为:
s/\d+(?= -max)/$data{$key}/ if exists $data{$key};
这仍然不能解释分数,但海报没有说明分数是否出现,如果出现,是否也应该更换。因此,我暂时不讨论它为了完整起见,这里有一个Python 3的解决方案:
with open("file2") as f:
times = dict(line.split() for line in f)
with open("file1") as in_f, open("file3", "w") as out_f:
for line in in_f:
fields = line.split(" ")
if fields[0] == "get_time":
fields[2] = times.get(fields[7], fields[2])
line = " ".join(fields)
out_f.write(line)
谢谢快速跟进。另一个类似的文件是这样的:get_time file123 tmp 10-max 5-min 0 abcde get_time file foo 9-max 5-min 0 abfdf get_time file43 bar 9-max 5-avg 3-min 0 xyxx如何修改脚本?再次感谢。考虑到替换可以包括分数,输入也可能包括分数,在这种情况下,
/\d+/
需要更像/d+(?:\。\d*)?/
,我认为。从文档中可以看出,该模块不在Perl的核心中,这对某些人来说可能是个小问题。@Jonathan Leffler我在输入中没有考虑分数。很高兴你注意到。使用Inline::Files避免创建要读取的文件。除非用于演示目的,否则不会使用它。@user1497417很难看出它是否位于示例行(如上)中的一行或多行上。也许你可以通过编辑你原来的帖子来发布它,像你得到的压缩一样,在quesitonI中显示行。地图分割,
技术很有趣,但逗号有点微妙;我可能会使用map{split}代码>取而代之。查看替换的另一种方法比将行拆分为单词、基于另一个单词替换一个单词并重新组合输出更简单。我不认为在这种情况下,存在
和定义
之间有实质性区别。请参阅我文章的更新。如果要替换的数字紧跟在-max
之前,那么我建议的更改就可以了。
abcde 8
abfdf 8.5
xyyxx 7.5
abcxx 9
.X1X.
.X2X.
.X3X.
get_time file 8 -max 5 -min 0 abcde
get_time file 8.5 -max 5 -min 0 abfdf
get_time file 7.5 -max 5 -avg 3 -min 0 xyyxx
get_time file 9 -max 5 -min 0 abcxx
.X4X.
.X5X.
.X6X.
#!/usr/bin/perl
use strict;
use warnings;
use Inline::Files;
my %data = map split, <FILE2>;
while (<FILE1>) {
if (my ($key) = /^get_time file .+ (\w+)$/) {
s/\d+/$data{$key}/ if exists $data{$key};
}
print;
}
__FILE2__
abcde 8
abfdf 8.5
xyyxx 7.5
abcxx 9
__FILE1__
.X1X.
.X2X.
.X3X.
get_time file 10 -max 5 -min 0 abcde
get_time file 9 -max 5 -min 0 abfdf
get_time file 9 -max 5 -avg 3 -min 0 xyyxx
get_time file 10 -max 5 -min 0 abcxx
.X4X.
.X5X.
.X6X.
get_time file123 tmp 10 -max 5 -min 0 abcde
get_time file foo 9 -max 5 -min 0 abfdf
get_time file43 bar 9 -max 5 -avg 3 -min 0 xyyxx
s/\d+(?= -max)/$data{$key}/ if exists $data{$key};
with open("file2") as f:
times = dict(line.split() for line in f)
with open("file1") as in_f, open("file3", "w") as out_f:
for line in in_f:
fields = line.split(" ")
if fields[0] == "get_time":
fields[2] = times.get(fields[7], fields[2])
line = " ".join(fields)
out_f.write(line)