簡體   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