繁体   English   中英

如何打开/加入多个文件(取决于用户输入)然后同时使用 2 个文件

[英]How to open/join more than one file (depending on user input) and then use 2 files simultaneously

编辑:很抱歉造成误解,我已经编辑了一些东西,希望能真正要求我想要的东西。

我想知道是否有办法打开/加入两个或多个文件来运行程序的 rest。

例如,我的目录有这些文件:

taggedchpt1_1.txt , parsedchpt1_1.txt , taggedchpt1_2.txt , parsedchpt1_2.txt等等...

程序必须同时调用一个标记和解析。 我想在 chpt1_1 和 chpt1_2 上运行该程序,最好在 one.txt 文件中连接在一起,除非这样做会很慢。 例如运行有两个文件可以完成的事情:

taggedchpt1_1_and_chpt1_2parsedchpt1_1_and_chpt1_2

这可以通过 Perl 完成吗? 或者我应该自己组合文本文件(或自动化该过程,制作 chpt1.txt,其中包括 chpt1_1、chpt1_2、chpt1_3 等......)

#!/usr/bin/perl
use strict;
use warnings FATAL => "all";
print "Please type in the chapter and section NUMBERS in the form chp#_sec#:\n"; ##So the user inputs 31_3, for example
chomp (my $chapter_and_section = "chpt".<>);
print "Please type in the search word:\n";
chomp (my $search_key = <>);

open(my $tag_corpus, '<', "tagged${chapter_and_section}.txt") or die $!;
open(my $parse_corpus, '<', "parsed${chapter_and_section}.txt") or die $!;

为了使程序的 rest 工作,我需要能够:

my @sentences = <$tag_corpus>; ##right now this is one file, I want to make it more
my @typeddependencies = <$parse_corpus>; ##same as above

EDIT2 : 真的很抱歉造成误解。 在程序中,在显示的步骤之后,我执行了 2 个 for 循环。 阅读标记和解析的行。

我想要的是使用来自同一目录的更多文件来完成此操作,而无需重新输入下一个文件。 (即。我可以运行 taggedchpt31_1.txt 和 parsedchpt31_1.txt ......我想运行 taggedchpt31 和 parsedchpt31 - 其中包括 ~chpt31_1、~chpt31_2 等......)

最终,如果我加入所有标记文件和所有具有共同章节的解析文件(最后仍然只需要我想要运行的两个文件)但不必将加入的文件保存到目录中,那将是最好的。 . 现在我把它变成文字,我想我应该只保存包含所有部分的文件。

抱歉,感谢您的所有时间。 查看 FMc 对我的问题的细分以获得更多帮助。

您可以遍历文件名,依次打开和读取每个文件名。 或者您可以生成一个知道如何从文件序列中读取行的迭代器。

sub files_reader {
    # Takes a list of file names and returns a closure that
    # will yield lines from those files.
    my @handles = map { open(my $h, '<', $_) or die $!; $h } @_;
    return sub {
        shift @handles while @handles and eof $handles[0];
        return unless @handles;
        return readline $handles[0];
    }
}

my $reader = files_reader('foo.txt', 'bar.txt', 'quux.txt');

while (my $line = $reader->()) {
    print $line;
}

或者你可以使用 Perl 的内置迭代器来做同样的事情:

local @ARGV = ('foo.txt', 'bar.txt', 'quux.txt');
while (my $line = <>) {
    print $line;
}

编辑以回应后续问题:

也许将您的问题分解为更小的子任务会有所帮助。 据我了解,您需要三个步骤。

  • 第 1 步是从用户那里获得一些输入——可能是目录名,或者可能是几个文件名模式( taggedchptparsedchpt )。

  • 第 2 步是让程序找到所有相关的文件名。 对于这个任务, glob()readdir()可能有用。 StackOverflow 上有很多与此类问题相关的问题。 您最终会得到两个文件名列表,一个用于标记文件,一个用于解析文件。

  • 第 3 步是处理这两组文件中所有文件的行。 您收到的大多数答案,包括我的,都会帮助您完成这一步。

你快到了...这比在每个文件上离散打开更有效...

#!/usr/bin/perl
use strict;
use warnings FATAL => "all";
print "Please type in the chapter and section NUMBERS in the for chp#_sec#:\n";
chomp (my $chapter_and_section = "chpt".<>);
print "Please type in the search word:\n";
chomp (my $search_key = <>);

open(FH, '>output.txt') or die $!;   # Open an output file for writing
foreach ("tagged${chapter_and_section}.txt", "parsed${chapter_and_section}.txt") {
    open FILE, "<$_" or die $!;      # Read a filename (from the array)
    foreach (<FILE>) {
       $_ =~ s/THIS/THAT/g;   # Regex replace each line in the open file (use 
                              #     whatever you like instead of "THIS" &
                              #     "THAT"
       print FH $_;           # Write to the output file
    }
}

还没有人提到@ARGV hack? 好的,就是这样。

{
    local @ARGV = ('taggedchpt1_1.txt', 'parsedchpt1_1.txt', 'taggedchpt1_2.txt',  
                   'parsedchpt1_2.txt');
    while (<ARGV>) {
       s/THIS/THAT/;
       print FH $_;
    }
}

ARGV是一个特殊的文件句柄,它遍历@ARGV中的所有文件名,关闭一个文件并根据需要打开下一个文件。 通常@ARGV包含您传递给perl的命令行 arguments ,但您可以将其设置为任何您想要的。

暂无
暂无

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

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