Запись в файл внутри, если оператор не работает в Perl - PullRequest
1 голос
/ 20 марта 2019

Я немного осмотрелся здесь и нашел похожие вопросы, но не совсем.Если он есть, я прошу прощения и укажу на него.

У меня есть следующий код.Я пытаюсь создать CSV-файл просто ID, извлеченный из имени файла и самого имени файла.Это ВЕСЬ сценарий.

use strict;
use warnings;
use File::Find;

find( \&findAllFiles, '.');
exit;

sub findAllFiles {

my @fp1;
my @fp2;
my $patId;
my $filename;
my $testvar = "hello again";


$filename = $File::Find::name;

if ($filename =~ /\.pdf$/) {
open (my $fh, '>', 'filenames.csv') or die "Failed to open - $!\n";
print $fh "starting...$testvar\n" or die "Failed to print to file - $!\n";
    @fp1 = split('/', $filename);
    @fp2 = split('_', $fp1[-1]);
    $patId = $fp2[-1];
    $patId =~ s/\.pdf$//;
    print "Adding $patId, file = $filename\n";
    print $fh "$patId,$filename\n" or die "File print error: $!";
close $fh or warn "close failed! - $!";
}


return;
}

Линия, которая выводится на экран, печатается отлично.Если я возьму файл open / close и первый оператор print из блока if, он напечатает эту строку в файле, но не данные внутри блока.Я перепробовал все комбо, которые только мог придумать, и это не сработало.Я чередовал '>' и '>>', поскольку ему явно требуется добавление, поскольку он циклически перебирает имена файлов, но ни один из них не работает внутри блока if.

Даже этот код выше не выбрасывает die ошибок!Он просто игнорирует эти строки!Я полагаю, что есть что-то очевидное, что мне не хватает.

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

Цитирование File::Find::find документация:

Кроме того, для каждого найденного каталога он будет выполнять вызов chdir () в этот каталог

Это означает, что когда вы open внутри findAllFiles, вы потенциально открываете файл filenames.csv внутри подкаталога вашего исходного каталога. Вы можете запустить что-то вроде find . -name filenames.csv из своего терминала, и вы увидите множество filenames.csv. Вы можете изменить это поведение, передав параметр no_chdir в find:

find( { wanted => \&findAllFiles, no_chdir => 1}, '.');

(и дополнительно изменить > на >> при вашем открытии)

Однако лично я бы избегал многократного открытия и закрытия filenames.csv, когда вы могли бы открыть его только один раз перед вызовом find. Если вы не хотите, чтобы ваш файловый дескриптор определялся глобально, вы всегда можете передать его в качестве аргумента findAllFiles:

{ 
    open my $fh, '>', 'filenames.csv' or die "Failed to open 'filenames.csv': $!";
    find(sub { findAllFiles($fh) }, '.')
}

sub findAllFiles {
    my ($fh) = @_;
    ...
1 голос
/ 20 марта 2019

filenames.csv будет создан в каталоге, где найден pdf, поскольку find () изменяет каталоги при поиске.Если это не то, что вам нужно, используйте абсолютный путь, чтобы открыть его (или откройте его перед вызовом find, что кажется лучшей идеей).

...