perl打开文件名中包含变量的文件

Pjo*_*ern 5 arrays perl file

我尝试打开文件夹中的文件列表.最后我想在其中插入一个HTML-Snippet.到目前为止,我可以打开文件夹并读取数组中的列表.没关系.但是当我尝试使用变量作为文件名打开文件时,我每次都会收到一条错误消息("权限被拒绝").无论我使用$ _还是将列表项的值放在变量中的其他变体.我在这里找到了类似的问题,但到目前为止还没有找到解决方案.这是我的代码:

use strict;
use warnings;

my ($line);

opendir (FOLDER,"path/to/folder/./") or die "$!";
my @folderlist = readdir(FOLDER);
my @sorted_folderlist = sort @folderlist;
close(FOLDER);

foreach (@sorted_folderlist) {
  my $filename = $_;
  open (READ, ">", "path/to/folder/$filename") or die "$!";
  # do something
  close (READ);
}
Run Code Online (Sandbox Code Playgroud)

这里有什么错误?我如何使用变量作为文件名打开文件?

Pjoern

这是我改变的代码,以回答1:

my $dh; 
opendir $dh, "dir/./" or die ... 
my @folderlist = grep { -f "dir/$_" } readdir $dh; 
close $dh; 
my @sorted_folderlist = sort @folderlist; 

foreach my $filename (@sorted_folderlist) { 
  open my $fh, "<", "dir/$filename" or die ... 
  open my $writeto, ">", "new/$filename" or die ... 
  print $writeto "$fh"; 
  close $fh; 
  close $writeto; 
}
Run Code Online (Sandbox Code Playgroud)

tin*_*ita 8

您的代码中有几个问题.

第一,导致了错误,很可能是,readdir()将返回...也,但这些目录.所以你试着写信给directory/..

其次,您的错误消息包含$!,这是好的,但您不输出文件名.然后你会看到你的错误.

第三,你打电话给你打开的文件句柄进行写作READ.

此外,您现在应该使用词法文件句柄.

use strict;
use warnings;

opendir my $dh, "dir" or die $!;
# read all files, not directories
my @folderlist = grep { -f "dir/$_" } readdir $dh;
close $dh;
my @sorted_folderlist = sort @folderlist;

foreach my $filename (@sorted_folderlist) {
    open my $fh, ">", "dir/$filename" or die "Could not write to dir/$filename: $!";
    print $fh "foo...\n";
    close $fh;
}
Run Code Online (Sandbox Code Playgroud)


zdi*_*dim 7

你在锡蒂塔的回答中找到了错误和良好做法.

我想评论一下可能的改进,即构建具有完整路径的文件列表.

注意区别:*in glob不会选择以dot(.)开头的条目.如果您也想要这些,请将其更改为glob "$dir/{*,.*}".请参阅链接的File::Glob文档.


更新   以更正问题的编辑(添加),也在评论中讨论

读入完整路径文件名后 @files

foreach my $file (@files) {
    my $out_file = 'new_' . $file;
    open my $writeto '>', $outfile or die "Can't open $outfile: $!";
    open my $fh,     '<', $file    or die "Can't open $file: $!";
    while (my $line = <$fn>) {
        # process $line and build what need be written to the new file
        my $new_line = ...   
        print $writeto $new_line;
    }
    close $writeto;
    close $fh;
}
Run Code Online (Sandbox Code Playgroud)

(或者,如果文件名不是完整路径,则构建open调用中的完整路径.)

再次打开时,close文件句柄会关闭,因此您只需要显示最后一个文件.然后你可以my ($fh, $writeto);在循环之前声明变量,使用open $fh ...(no my),然后关闭文件句柄.但是你有那些变量超出foreach范围.

文档:


glob "$dir/*"对于非常特殊的目录名称,   它具有注入错误的可能性.虽然这只能产生相当不寻常的名称,但使用转义序列会更安全

my @files = grep { -f } glob "\Q$dir\E/*"
Run Code Online (Sandbox Code Playgroud)

由于该逃逸空间以及在File::Glob与它bsd_glob()是没有必要的.