【问题标题】:Script to scan the folder the script is in and search for specific files [Perl]用于扫描脚本所在文件夹并搜索特定文件的脚本 [Perl]
【发布时间】:2017-08-20 19:24:21
【问题描述】:

我正在创建一个在特定文件夹中打开的脚本,其中包含两种不同类型的文件。 “安全”(secure.text、secure.001.text 等)文件和“消息”(message.txt 等)文件。每个文件包含年、日、日期、小时和分钟的日志。我希望能够扫描这些文件并创建一个包含 2006 年 1 月的所有日志条目的新文件。此脚本的目的是能够仅扫描一组数据(安全),而不是全部(消息)。

我的脚本查找当前工作目录时遇到问题。据我了解,perl 将使用脚本的位置作为当前目录。我正在使用opendir和closedir函数,提示脚本目录中有60个文件,但是当我删除一些文件只是为了测试它时,它仍然显示60,让我相信这不是使用当前目录。尽管正则表达式正确,它也没有找到“安全”。

我得到的输出是“问题查找文件'安全'。”

#!/usr/bin/perl


use strict;
use warnings;



#Locate and scan all of the files 

 #list all files in same dir as this perl script.
 my $dirname = "."; 
 opendir( my $dh, $dirname ) #sets $dh as the current working directory
    or die "Can't open dir '$dirname':$!\n"; #Kills if can not open current directory.
 my @all_the_file; #Instantiates new variable that accounts for all of the files in the current dir.
 while( my $file = readdir($dh) ) { #$file accounts for every file on device. 
    push( @all_the_file, $file ); #Pushes files in current directory to $file.

 }
 closedir( $dh ); 

 #Gets all of the secure files. 

 my @all_the_secure_file;
 @all_the_secure_file = grep(/^secure(\.\d{1,2})?$/, @all_the_file);

 #Itterate over secure files. 

my $filename = "secure";
open( my $fhin, "<", $filename)
    or die "Can't open '$filename':$!\n";
chomp( my @lines = <$fhin> ) ;
close($fhin);

 #Match the Regex of Jan. 

 my @jan_lines = grep( /^Jan/ , @lines ) ;
print "The file '$filename' = " . @lines . " lines.\n";
print "Size of \@jan_lines = " . @jan_lines . "\n";

 #Print and create new file with Data. 

 my $filename2 = "secure.1";
open( my $fhin, "<", $filename)
    or die "Can't open '$filename':$!\n";
chomp( my @lines2 = <$fhin> ) ;
close($fhin);

my @jan_lines2 = grep( /^Jan/ , @lines2 ) ;
print "The file '$filename2' = " . @lines2 . " lines.\n";
print "Size of \@jan_lines2 = " . @jan_lines2 . "\n";

 exit;

【问题讨论】:

  • 脚本的位置不一定是当前工作目录。当前工作目录是当前工作目录。例如,查看 CwdFindBin 模块。
  • 另外,“迭代安全文件”和“打印并使用数据创建新文件”实际上并没有像 cmets 所说的那样......
  • 基本调试:(1)设置$dirname为实际路径(硬编码)(2)你从opendir得到的没有路径!因此,将 $dirname 添加到 opendir 返回的内容之前。 // 然后你将扫描$dirname 中的文件。 // 请不要删除文件进行测试!为什么不直接将它们打印到屏幕上并检查它们是否正确?请记住,他们需要有完整的路径。您还可以使用if (not -f $file) { print "No $file\n" } 进行测试,您将看到这些字符串(名称$file)是否是系统上的实际文件。 // 还有其他问题,但这是一个开始。
  • 如何使当前工作目录成为运行脚本的目录?这本质上是本文的主要重点,这样我就可以在脚本中更改文件的名称,并有一个程序来为我组织文件。
  • 您是否阅读了我在上面的评论中包含的链接?

标签: perl file search directory


【解决方案1】:

你真的应该使用一些模块。以下示例使用Path::Tiny

use 5.014;
use warnings;
use Path::Tiny;

my $root = path("/some/path");
my $iter = $root->iterator({recurse => 1});

while(my $path = $iter->()) {
    next unless $path->basename =~ /(secure|message)\.(\d+)?\.txt/i;

    my $type = $1;
    #my $num = $2; #???

    my @lines = grep { /^Jan/ } $path->lines();
    say "in the $path is ", scalar @lines, " lines for Jan";

    my $new = path( ($type =~ /secure/i) ? "/some/where/secure.txt" : "/some/nosecure/message.txt" );
    $new->spew(@lines);
}

未测试,但它应该做 +- 与您的脚本相同,更因为它递归搜索...

【讨论】:

  • 是路径("/some/path");设置文件所在位置的默认路径?
  • @MatthewParise 如果“默认路径”是指完整路径,是的。如果您必须使用相对于脚本运行位置的路径,您可以使用FindBin(和Cwd)找到它,然后构建它的完整路径,然后您仍然可以使用这个很棒的模块。这个答案为您提供了几乎所有您需要的东西,以及未来使用的蓝图。
  • @MatthewParise 嗯...抱歉,path($dir)/some/path 处为文件/目录构造一个对象。它在这里分配给$root,之后您可以在$root 上调用模块的方法。 path() 采用文件/目录的完整路径,这就是 /some/path 的含义(这就是我在上面评论中的意思)。
猜你喜欢
  • 2011-12-07
  • 2017-07-29
  • 2017-03-19
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多