读取2个文件并替换另一个文件中某些文件的某些值的脚本

时间:2012-07-19 16:09:58

标签: 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

.

.

.

我需要的是一个文件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 

您如何修改脚本?再次感谢

3 个答案:

答案 0 :(得分:1)

将文件2读入哈希或字典,其中键是5个字母的标记。

一次读取一行文件1,将第三列中的值替换为散列或字典中根据行末显示的标记找到的值。


的Perl

#!/usr/bin/env perl
use strict;
use warnings;
use English qw( -no_match_vars );

my %times;

$OFS = " ";

open my $file, "<", "file2" or die "Failed to open file2 ($!)";
while (<$file>)
{
    my($key,$value) = split;
    $times{$key} = $value;
}
close $file;

while (<>)
{
    if (/^get_time file/)
    {
        my(@words) = split;
        my($keycol) = $words[$#words];
        $words[2] = $times{$keycol} if defined $times{$keycol};
        print @words, "\n";
        next;
    }
    print;
}

我没有声称它是最高级的Perl;它似乎确实有用:

文件1

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

file2的

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.

答案 1 :(得分:1)

我以为我会发布一个最高级的Perl 解决方案。 ; - )

#!/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.

结果与Jonathan的解决方案相同。

<强>更新 user1497417询问如何在第一篇文章中解析一些与他想要改变的格式不同的格式。这3行是:

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};

这仍然不考虑分数,但海报没有说明它们是否发生,如果是,它们是否应该被替换。所以,我现在暂时离开它

答案 2 :(得分:0)

为了完整起见,这是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)