如何检查Perl中是否存在具有特定字符串的文件名

时间:2016-05-30 15:47:59

标签: perl

我在Perl中重写一个Bash脚本以便学习后者。

该脚本使用自定义格式的当前日期和“.txt”扩展名创建文件,但首先检查以确保没有相关日期的文件已存在。

在Bash中,我以ls |grep $customDate为条件完成此操作。也就是说,如果ls |grep $customDate为真,则会发出警告并且没有创建文件,而如果ls |grep $customDate为false,则会使用自定义日期加上“.txt”扩展名创建文件

我如何在Perl中模仿这个?

出于测试目的,我编写了下面的代码,但它没有打印出任何内容 - 即使我创建的文件符合条件:

use POSIX qw( strftime );

$customDate = strftime "%Y_%m%b_%d%a", localtime;

opendir(DIR, ".") or die "$!";
my @FILES  = grep { /${customDate}*/ } readdir(DIR);
closedir(DIR);

print "$_\n" for @FILES;

如果我的问题不清楚,我道歉

2 个答案:

答案 0 :(得分:0)

  

“我正在重写Perl中的Bash脚本以学习后者。”

我认为你采用错误的方法学习Perl或学习任何语言。

虽然程序语言之间总是存在很多相似之处,但重点关注差异之上的那些语言总是错误的。如果你希望能够很好地阅读和编写它们,必须从头开始学习编程语言

我经常在Stack Overflow上看到Perl代码,这些代码显然是由错误的人写的。例如,C程序员最明显的迹象是

  • 在源文件顶部的一个块中声明所有

  • 过度使用scalar和括号

  • 未使用默认变量 $_和正则表达式

  • 使用C风格的for循环,在Perl中通常看起来像这样

    my $i;
    
    for ($i=0; $i<=scalar(@data); $i++)
    {
        process($data[$i])
    }
    

    除了完全忽略perlstyle之外,作者正在抓住熟悉的东西而不是接受新语言。在惯用的Perl中应该看起来像

    process($_) for @data
    

进一步深入,很容易对你可能在shell中写出的短语的后果感到自满

你需要知道你的shell语句

ls |grep $customDate

正在启动新进程以运行/bin/ls/bin/grep,并在它们之间传递信息并返回到shell进程。 Linux shell及其支持实用程序旨在轻松完成繁琐的工作,但我相信它们被过多地用于精心制作的shell脚本 one-liners ,它们不透明且无法调试


很难确切地知道你需要你的程序做什么,但看起来你想要发现当前目录中是否有任何包含2016_05May_30Mon字符串的文件

我不得不说这是一个糟糕的日期时间格式,我很难相信它是你想要的,但我更喜欢Perl的核心Time::Piece模块而不是POSIX

在这个例子中,我还会使用Perl的正则表达式,-X *文件测试运算符和Perl的glob运算符,而不是opendirreaddir,{ {1}}。这些都没有直接等效于任何shell语言

所以,假设我对你的意图的猜测是正确的,我会写这个

closedir

这与您从shell到Perl

的翻译并不遥远

答案 1 :(得分:-1)

你没有得到预期的原因是grep中的*正在寻找&#34; $ customDate&#34;的最后一个字符。重复多次(在这种情况下,这不是你对*的期望)。

如果您的文件有&#34; somedata.txt&#34; ext,您应该更新代码,这将查找您的日期字符串,然后查找任意数量的字符后跟一个txt:

$customDate = strftime "%Y_%m%b_%d%a", localtime;

opendir(DIR, ".") or die "$!";
my @FILES  = grep { /${customDate}.*\.txt/ } readdir(DIR);
closedir(DIR);

print "$_\n" for @FILES;