【问题标题】:Reading content from Multiple Text Files从多个文本文件中读取内容
【发布时间】:2010-12-13 07:25:05
【问题描述】:

寻求帮助:

我有一个目录,其中包含以数字 ID 命名的文本文件。每个文本文件都包含新闻文章的正文。一些新闻文章被分隔在不同的部分,因此它们位于不同的文本文件中。

名字是这样的

1001_1.txt、1001_2.txt(这些文件包含同一篇文章的两个不同部分) 1002_1.txt, 1003_1.txt, 1004_1.txt, 1004_2.txt, 1004_3.txt, 1004_4.txt(这些文件包含同一篇文章的四个不同部分,这些部分最多只能达到 4 个)。

等等等等。

基本上,我需要一个简单的脚本(PHP、Perl、RUBY 或其他) 列中文本文件的名称(下划线之前),以及 另一列中文本文件的内容,如果有任何数字 在下划线之后,也将其放在一列中。

所以你会有一个如下所示的表结构:

    1001 | 1 | content of the text file
    1001 | 2 | content of the text file
    1002 | 1 | content of the text file
    1003 | 1 | content of the text file

任何关于如何完成此任务的帮助将不胜感激。

大约有7000个文本文件需要读取和导入 供将来在数据库中使用的表。

如果 _1 和 _2 文件的内容可以是更好的 分隔在不同的列中,例如:

    1001 | 1 | content | 2 | content | 3 | content | 4 | content
    1002 | 1 | content
    1003 | 1 | content

(就像我说的,文件名最多可达_4 所以你可以有1001_11001_21001_31001_4.txt或只有1002_11003_1.txt)

【问题讨论】:

  • 你想如何解析输出,格式对我来说似乎很奇怪没有换行符?
  • 如果您让我们知道您的尝试,Amit 会很好,我们不是来做您的工作的...
  • 我对歪曲 OP 的意图表示不认罪。帖子的原始格式在这里:stackoverflow.com/revisions/…
  • 我想知道一个人在这里花多少时间回答问题?下面的代码至少需要 10 分钟来编写。那么,人们会花 10 分钟来回答问题吗?
  • 大家好,我是第一次来这里,mobrule,感谢您格式化我的帖子。 RageZ,老实说,除了 PHP 和一点 C 语言之外,我没有任何其他语言的经验,尽管我是一个快速学习者,并且当指向正确的方向时,我可以弄明白。哦,Mob,你没有误解我的意图,即使你的格式保持不变。

标签: php ruby perl


【解决方案1】:

File::FindFile::Slurp 相当简单:

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;
use File::Slurp;

die "Need somewhere to start\n" unless @ARGV;

my %files;
find(\&wanted, @ARGV);

for my $name (sort keys %files) {
    my $file = $files{$name};
    print join( ' | ', $name,
        map { exists $file->{$_} ? ($_, $file->{$_}) : () } 1 .. 4
    ), "\n";
}

sub wanted {
    my $file = $File::Find::name;
    return unless -f $file;
    return unless $file =~ /([0-9]{4})_([1-4])\.txt$/;
    # I do not know what you want to do with newlines
    $files{$1}->{$2} = join('\n', map { chomp; $_ } read_file $file);
    return;
}

输出:

1001 | 1 | lsdkjv\nsdfljk\nsdklfjlksjadf\nlsdjflkjdsf | 3 |悲伤的 1002 | 1 | ldskfjsdlfjkl

【讨论】:

  • 效果很好,谢谢!我安装了这两个模块,但似乎 File::Find 是用 perl 5.10 预构建的。给了我我需要的东西。
【解决方案2】:
use strict;
use warnings;
my %content;

while (<>){
    s/\s+/ /g;
    my ($f, $n) = $ARGV =~ /(\d+)_(\d)\.txt$/;
    $content{$f}{$n} .= $_;
}

for my $f (sort keys %content){
    print join('|',
        $f,
        map { $_ => $content{$f}{$_} } sort keys %{$content{$f}},
    ), "\n";
}

【讨论】:

    【解决方案3】:

    可能不是最佳的,但可能是您的起点(故意过度评论):

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    # results hash
    my %res = ();
    
    # foreach .txt files
    for (glob '*.txt') {
        s/\.txt$//; # replace suffix .txt by nothing
        my $t = ''; # buffer for the file contents
        my($f, $n) = split '_'; # cut the file name ex. 1001_1 => 1001 and 1
    
        # read the file contents
        {
            local $/; # slurp mode
            open(my $F, $_ . '.txt') || die $!; # open the txt file
            $t = <$F>; # get contents
            close($F); # close the text file
        }
    
        # transform \r, \n and \t into one space
        $t =~ s/[\r\n\t]/ /g;
        # appends for example 1001 | 2 | contents of 1001_2.txt to the results hash
        $res{$f} .= "$f | $n | $t | ";
    }
    
    # print the results
    for (sort { $a <=> $b } keys %res) {
        # remove the trailing ' | '
        $res{$_} =~ s/\s\|\s$//;
        # print
        print $res{$_} . "\n";
    }
    
    # happy ending
    exit 0;
    

    【讨论】:

    • 太棒了。感谢您的“过度评论”,这对理解发生的事情有很大帮助,因为我真的没有使用 Perl 的经验。这反过来也有助于自定义脚本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    相关资源
    最近更新 更多