1

我有多个扩展名为.tdx.

目前我的程序使用 . 处理单个文件$ARGV[0],但是文件数量正在增长,我想使用基于文件扩展名的通配符。

经过大量研究,我不知所措。

我想单独读取每个文件,以便用户识别文件中的提取物。

#!C:\Perl\bin\perl.exe

use warnings;

use FileHandle;

open my $F_IN,  '<', $ARGV[0]     or die "Unable to open file: $!\n";
open my $F_OUT, '>', 'output.txt' or die "Unable to open file: $!\n";

while (my $line = $F_IN->getline) {
  if ($line =~ /^User/) {
    $F_OUT->print($line);
  }
  if ($line =~ /--FTP/) {
    $F_OUT->print($line);
  }
  if ($line =~ /^ftp:/) {
    $F_OUT->print($line);
  }
}
close $F_IN;
close $F_OUT;

所有文件都在一个目录中,所以我假设我需要打开该目录。

我只是不确定我是否需要构建一个文件数组或构建一个列表并将其切碎。

4

4 回答 4

2

你有很多选择——

  1. 循环@ARGV,允许用户传入文件列表
  2. 用于glob传入 perl 将扩展为文件列表的模式(然后循环该列表,如 #1 中所示)。这可能会很混乱,因为他们必须确保引用它,以便 shell 不会首先插入它。
  3. 编写一些包装器来一遍又一遍地调用您现有的脚本。

还有第一个的变体,它是从<>. 这设置为 STDIN,或者它会自动打开以@ARGV. eof有关如何使用它的示例,请参阅。

作为#2 的变体,您可以传入目录名称,并使用opendirandreaddir来遍历列表(确保仅抓取带有扩展名的文件,或者至少忽略.and ..)或附加/*or/*.tdx并使用glob再次。

于 2013-11-14T01:23:10.527 回答
0

我从来没有得到 glob 工作。我最终做的是基于文件扩展名 .tdx 构建一个数组。从那里我将数组复制到文件列表并从中读取。我最终得到的是:

#!C:\Perl\bin\perl.exe
use warnings;
use FileHandle;
open my $F_OUT, '>', 'output.txt' or die "Unable to open file: $!\n";
open(FILELIST, "dir /b /s \"%USERPROFILE%\\Documents\\holding\\*.tdx\" |");
@filelist=<FILELIST>;
close(FILELIST);
foreach $file (@filelist)
            {
            chomp($file);
            open my $F_IN,  '<', $file     or die "Unable to open file: $!\n";
            while (my $line = $F_IN->getline) 
              {
Doing Something
              }
            close $F_IN;
            }
close $F_OUT;

感谢您在学习过程中提供的帮助。

于 2013-11-14T16:53:05.877 回答
0

glob功能可以帮助您。试试看嘛

my @files = glob '*.tdx';
for my $file (@files) {
    # Process $file...
}

在列表上下文中,glob将其参数扩展为与模式匹配的文件名列表。有关详细信息,请参阅perlfunc 中的 glob

于 2013-11-14T01:20:08.157 回答
0

如果您使用的是 Windows 机器,*.tdx则在命令行上输入可能不起作用,也可能无法glob使用过去使用 shell 的通配能力。(现在看来,内置glob函数现在使用File::Glob,因此这可能不再是问题)。

您可以做的一件事是不使用 glob,而是允许用户输入他们想要的目录和后缀。然后使用opendirandreaddir自己浏览目录。

use strict;
use warnings;
use feature qw(say);
use autodie;
use Getopt::Long;      # Why not do it right?
use Pod::Usage;        # It's about time to learn about POD documentation

my @suffixes;  # Hey, why not let people put in more than one suffix?
my @directories;       # Let people put in the directories they want to check
my $help;

GetOptions (
    "suffix=s"     => \@suffixes,
    "directory=s"  => \@directories,
    "help"         => \$help,
) or pod2usage ( -message => "Invalid usage" );

if ( not @suffixes ) {
    @suffixes = qw(tdx);
}

if ( not @directories ) {
    @directories = qw(.);
}

if ( $help ) {
    pod2usage;
}

my $regex = join, "|",  @suffixes;
$regex = "\.($regex)$";   #  Will equal /\.(foo|bar|txt)$/ if Suffixes are foo, bar, txt

for my $directory ( @directories ) {
    opendir my ($dir_fh), $directory;   # Autodie will take care of this:
    while ( my $file = readdir $dir_fh ) {
        next unless -f $file;
        next unless $file =~ /$regex/;
        ... Here be dragons ...
    }
}

这将遍历用户输入的所有目录,然后检查每个条目。它使用用户输入的后缀(.tdx默认为)来创建正则表达式来检查文件名。如果文件名与正则表达式匹配,请对该文件执行您想要执行的任何操作。

于 2013-11-14T17:52:48.797 回答