2009-11-05 4 views
0

Ищет помощь в этом:Чтение содержимого из нескольких текстовых файлов

У меня есть каталог, полный текстовых файлов, названных с числовым идентификатором. Каждый текстовый файл содержит текст новостной статьи. Некоторые новостные статьи разделены на разные части, поэтому они находятся в разных текстовых файлах.

Имена таких

 
1001_1.txt, 1001_2.txt (These files contain two different part of the same article) 
1002_1.txt, 
1003_1.txt, 
1004_1.txt, 1004_2.txt, 1004_3.txt, 1004_4.txt (these files contain four different parts of the same article, the parts will go up to a maximum of 4 only). 

и так далее, и так далее.

В принципе, мне нужен скрипт (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 файлов может быть выделено в разных colums, например:

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

(Как я уже сказал, имена файлов идут максимум до _4 , чтобы вы могли есть 1001_1, 1001_2, 1001_3, 1001_4.txt или только 1002_1 и 1003_1.txt)

+0

, как вы хотите, чтобы разобрать вывод, формат кажется мне странным, нет новой строки? – RageZ

+1

@mobrule Я так думаю! – RageZ

+3

Амиту было бы хорошо, если бы вы сообщили нам, что вы пробовали, мы здесь не для того, чтобы выполнять вашу работу ... – RageZ

ответ

2

Это довольно просто с File::Find и File::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 | sadlfkjldskfj 
1002 | 1 | ldskfjsdlfjkl 
+0

отлично работает, спасибо! Я установил два модуля, хотя кажется, что File :: Find подготовлен с помощью perl 5.10. Дал мне именно то, что мне нужно. –

0

Вероятно, не является оптимальным, но могла бы быть ваша стартовая пункт (более комментировал цели):

#!/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; 
+0

удивительный. Спасибо за «Over-commenting», очень помогли понять, что происходит, поскольку у меня действительно нет опыта работы с Perl. Это, в свою очередь, помогает в настройке скрипта. –

+0

Это была цель :) – 2009-11-06 21:47:23

1
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"; 
} 
Смежные вопросы