【问题标题】:Merging two txt files by the list in first file and keeping the same list in output通过第一个文件中的列表合并两个 txt 文件并在输出中保持相同的列表
【发布时间】:2012-03-13 05:19:45
【问题描述】:

我有两个文件,一个有一个代码列表,另一个有一个带有名称的代码列表,并且是用竖线分隔的。

例如:)文件 1:

00001
00002
00001
00003
00002
00004

文件 2:*注意某些名称可能是名称 1 1 等。请参阅下面的新示例:

00001 | name1 1 1
00002 | name2 2
00003 | name3 3 3 3
00004 | name4 4 4 4 4

我需要输出在文件 1 中保持相同的结构,但从文件 2 中获取名称,如下所示:

输出文件:

00001 | name1 1 1
00002 | name2 2
00001 | name1 1 1
00003 | name3 3 3 3
00002 | name2 2
00004 | name4 4 4 4 4

等等。我一直在使用我找到并修改的 Perl 脚本,以便从第一个文件中逐行查找文件中的匹配项:

    #!/usr/bin/perl -w
    use strict;
    #FindTextInFile.pl
    my ($names, $data) = ("codesonly.txt", "codeandtext.txt");
    open (FILE1, $names) || die;
    open (FILE2, $data) || die;
    undef $/; #Enter "file-slurp mode" by emptying variable indicating end-of-record
    my $string = <FILE2>; #Read entire file to be searched into a string variable
    $/ = "\n"; #Restore default value to end-of-record variable

    while (<FILE1>) {
        chomp; #remove new-line character from end of $_
        #Use quotemeta() to fix characters that could spoil syntax in search pattern
        my $qmname = quotemeta($_);


        if ($string =~m/$qmname/i) {
                    print " $_  \n";
        }
        else {

        }

    }

我也一直在 Windows CMD 命令中使用 FINDSTR 函数,但它不会为我逐行输出。我对 PERL 很陌生,所以任何帮助都会很棒,或者如果有更简单的方法可以做到这一点,那将非常有帮助。我将使用的文件约为 1M 行,所以我需要一些快速的文件。

谢谢

【问题讨论】:

  • 除非你真的打算自己写,否则试试join

标签: perl


【解决方案1】:

使用散列进行快速轻松的查找。

my %rows;
{
   open(my $names_fh, '<', $names_qfn)
      or die("Can't open \"$names_qfn\": $!\n");

   while (<$names_fh>) {
      my ($id) = /^(\S+)/;
      $rows{$id} = $_;       
   } 
}

{
   open(my $index_fh, '<', $index_qfn)
      or die("Can't open \"$index_qfn\": $!\n");

   while (<$index_fh>) {
      chomp;
      print($rows{$_});
   }
}

【讨论】:

  • 感谢池上的回复。我一直试图让这段代码工作,但不能。当我为我的文件运行它时,我没有得到任何结果。有什么想法吗?
  • @user1258104,代码运行良好,即使您更新了数据。你真的把文件名$names_qfn$index_qfn 放在了上面吗?请告诉我你也用过use strict; use warnings;?永远!!!
【解决方案2】:

大概是这样的吧?

use strict;
use warnings;

my %codes = do {
  local $/;
  open my $fh, '<', 'f2.txt' or die $!;
  <$fh> =~ /\w+/g;
};

open my $fh, '<', 'f1.txt' or die $!;
while (<$fh>) {
  my ($key) = /(\w+)/;
  print "$key | $codes{$key}\n";
}

输出

00001 | name1
00002 | name2
00001 | name1
00003 | name3
00002 | name2
00004 | name4

【讨论】:

  • 感谢鲍罗丁的回复。它有效,但我还应该提到一些名称有空格。
【解决方案3】:

感谢大家的回复。我可以用这段代码做我需要的事情。

    open(file1, "<file1.txt");
    open(file2, "<file2.txt");

    while(<file2>){
            my($line) = $_;
            chomp $line;
            my($key, $value) = $line =~ /(.+)\|(.+)/;
            $file2Hash{$key} = $value;
    }

    while(<file1>){
            my($line) = $_;
            chomp $line;
            if(exists $file2Hash{$line}){print $line." | ".$file2Hash{$line}."\n";}
            else{print $line." | "."Error - Key not found in hash\n";}
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多