简体   繁体   English

Perl:如何从子目录读取文件?

[英]Perl: how do I read a file from a subdirectory?

I'm really new to Perl, so excuse me if I missed an obvious answer. 我对Perl真的很陌生,所以如果我错过了一个明显的答案,请原谅。 I will appreciate all help. 我将不胜感激。

I'm trying to read a file that is located in a subdirectory, so I can extract some information, and print the information into a new file. 我正在尝试读取位于子目录中的文件,因此我可以提取一些信息,然后将信息打印到新文件中。

I know how to read a file in the current directory (and print into a new file): 我知道如何读取当前目录中的文件(并打印到新文件中):

open IN, "$file_name" or die "No such file: !$";
open OUT, ">$new_file_name" or die " No such file: !$";

while (<IN>) {
print OUT $_;
}

but how do I do this to a file that is located in a subdirectory? 但是如何对位于子目录中的文件执行此操作?

Many thanks, 非常感谢,

Nika 尼卡

EDIT: 编辑:

Thank-you all very very much! 非常感谢大家! I've solved the problem! 我已经解决了问题!

open takes a path , so open需要一条 ,所以

my $file_name = 'subdir/file.ext';

Here's your code with many improvements: 这是您的代码,具有许多改进:

open my $IN, '<', $in_qfn
    or die "Can't open \"$in_qfn\": $!\n";

open my $OUT, '>', $out_qfn
    or die "Can't create \"$out_qfn\": $!\n";

while (<$IN>) {
    print $OUT $_;
}

I'd actually use ARGV and STDOUT for maximum flexibility if possible. 如果可能的话,我实际上会使用ARGV和STDOUT来获得最大的灵活性。

while (<>) {
    print;
}

There are two obvious ways: 有两种明显的方法:

  1. Access the file by its full path name, ie the value of $file_name must be something like directoryname/filename.txt or you write "directoryname/$filename" in your first line of code. 通过文件的完整路径名访问文件,即$file_name的值必须类似于directoryname/filename.txt或在第一行代码中写入"directoryname/$filename"

  2. Change the working directory. 更改工作目录。 That is, use the Perl chdir function to change the working directory before accessing the file: chdir "directoryname"; 也就是说,在访问文件之前,使用Perl chdir函数更改工作目录: chdir "directoryname"; Keep in mind that this affects all subsequent file systems operations. 请记住,这会影响所有后续文件系统操作。 If you want to go back, use chdir ".."; 如果要返回,请使用chdir ".."; .

In either case, it is very helpful to familiarize yourself with the concept of working directory, special directory names ( . and .. ), the path separator / , relative and absolute paths and how file systems work in general. 无论哪种情况,熟悉工作目录,特殊目录名( ... ),路径分隔符/ ,相对路径和绝对路径以及文件系统的一般工作原理都是很有帮助的。

Just give it a full path to the directory. 只需为其提供完整路径即可。 you can use the pwd command to get the full path if you are in the directory where file is located. 如果您位于文件所在的目录中,则可以使用pwd命令获取完整路径。 Note, you should always use the qualified/full path to files because you never know from where the script might be invoked. 注意,您应该始终使用文件的限定/完整路径,因为您永远不知道从何处可以调用脚本。 (it's just good programming practice) (这只是良好的编程习惯)

use strict;
use warnings;

my $filename = 'your_full/path/sub_dir/data.txt';
if (open(my $fh, '<:encoding(UTF-8)', $filename)) {
while (my $row = <$fh>) {
chomp $row;
print "$row\n";
}
} else {
warn "Could not open file '$filename' $!";
}

Your variables (or strings) may contain the relative path to the file so simply say 您的变量(或字符串)可能包含文件的相对路径,所以简单地说

open IN, "foo/$file1"

Oh and use 3-argument open . 哦, 使用3参数open

You can simply give the name of the file in the subdirectory. 您可以简单地在子目录中提供文件名。 Use the forward slash to separate the directory from the sub directory. 使用正斜杠将目录与子目录分开。

Here's your program written in a bit more modern fashion: 这是您的程序以更现代的方式编写:

use strict;
use warnings;
use autodie;
use feature qw(say);

my $file_name = "path/to/file";
my $new_file_name = "path/to/new/file";

open my $in_fh, "<" $file_name;
open my $out_fh, ">", $new_file_name;

while my $line ( <$in_fh> ) {
    print {$out_fh} $line;
}
close $in_fh;
close $out_fh;
  • use strict; requires you to declare your variables which can save you a lot of hassle. 要求您声明变量,这样可以节省很多麻烦。 For example, you say $foo on place and $Foo (with a capital F ) in another. 例如,您说的是$foo ,而另一个是$Foo (大写F )。 With use strict; use strict; , Perl will catch these errors for you. ,Perl将为您捕获这些错误。 You declare a variable with my or our . 您使用myour声明变量。 99% of the time, you will use my . 99%的时间,您将使用my
  • use warnings; turns on all sorts of warnings. 打开各种警告。 For example, you are attempting to do something with a variable that is undefined. 例如,您尝试使用未定义的变量进行操作。
  • use autodie automatically will kill your Perl script in many circumstances. 在许多情况下,自动use autodie将杀死您的Perl脚本。 For example, you can't open or close a file. 例如,您无法打开或关闭文件。 Or, what if the disk is full, and your print statement can't print to the file? 或者,如果磁盘已满,而您的print语句无法打印到该文件怎么办?
  • use feature qw(say); allows you to use say instead of print . 允许您使用say代替print The say command will automatically add a NL to the end of the line for you which is a lot more convenient than it sounds. say命令会自动为您在行尾添加NL,这比听起来容易得多。
  • Use three parameter open and close , and use variable names for the file handle. 使用三个参数 openclose ,并为文件句柄使用变量名。 This makes passing the file handle easier to do to subroutines. 这使得将文件句柄传递给子例程更容易。
  • Don't use the default $_ when you don't have to. 不必使用默认的$_ There are many issues with using it (which I am not going to get into right now. It really doesn't add clarity to the program, and will many times get you into trouble. 使用它有很多问题(我现在不打算讨论。它确实并没有增加程序的清晰度,并且很多时候会给您带来麻烦。
  • Use close when you finish with a file. 完成文件后,请使用close

You should get a good book on Modern Perl . 您应该得到一本有关Modern Perl的好书。 For example, in your program, I could have done this: 例如,在您的程序中,我可以这样做:

use strict;
use warnings;
use autodie;
use feature qw(say);

use File::Copy;    # Adds a `copy` command to Perl

use constant {     # Adds the concept of a constant to Perl
    IN_FILE   =>  'path/to/file',
    OUT_FILE  =>  '/paht/to/new/file',
};

copy IN_FILE, OUT_FILE;   # That's it!

No need to open files. 无需打开文件。 No need to use loops. 无需使用循环。 The copy command will do it for you. copy命令将为您完成此操作。

These modules like File::Copy are available in the standard installations of Perl. 这些模块,例如File::Copy在Perl的标准安装中可用。 You need to learn about them, so you can use them. 您需要了解它们,以便可以使用它们。 This is why you should get a good book and go through it. 这就是为什么您应该获得一本好书并仔细阅读的原因。

Have fun with Perl, and please learn the right way of doing things. 与Perl一起玩乐,请学习正确的做事方式。 It makes Perl a much easier language to use and learn. 它使Perl成为易于使用和学习的语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM