Perlスクリプトでfindコマンドを使用する方法は?

Perlスクリプトでfindコマンドを使用する方法は?

findコマンドが常に指定されたディレクトリではなくルートディレクトリに移動する理由を誰でも教えてもらえますか$srceDir

my $srceDir = "/mnt/SDrive/SV/Capture Data/";

my $find_cmd = 'find $srceDir -type f -newermt 2013-02-14 ! -newermt 2013-02-15';

open(FIND_FILE, "$find_cmd |");
while(<FIND_FILE>){ 
    next if /^total/; # because we're only interested in real output
    print $_; 
}

ベストアンサー1

これは二重引用符の代わりに一重引用符を使用するためです。

Perlはそうではありません一重引用符で囲まれた変数の挿入だから、あなたがすることは '$ srceDir'文字列をシェルに送ることです。この文字列は、環境のどこかに設定しない限り、通常は設定解除(空)されます。

この試み:

my $find_cmd = "find $srceDir -type f -newermt 2013-02-14 ! -newermt 2013-02-15";

または、より良い方法は次のとおりです。

my $find_cmd = sprintf
    'find "%s" -type f -newermt 2013-02-14 ! -newermt 2013-02-15',
    $srceDir;

...空間に配慮しながら検索コマンドforkedで実行されますsh

*重要事項*

@vonbrandが正しく言及したように:プログラムと他の多くのものとの間の通信を確実にするために、実際には多くのライブラリが提供されている。

ファイルシステムを操作するために、findPerlはFileライブラリモジュールを使用します。これを行うには、コマンドラインを小さなPerlスクリプトに変換する小さなFile::Findユーティリティがあります。find2perlfind

$ find2perl -type f -mtime -3 ! -mtime -2;
#! /usr/bin/perl -w
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
        if 0; #$running_under_some_shell
use strict;
use File::Find ();

# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

sub wanted;

# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '.');
exit;

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);
    (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
    -f _ &&
    (int(-M _) < 3) &&
    ! (int(-M _) < 2)
    && print("$name\n");
}

したがって、お客様の要件は次のとおりです。

#! /usr/bin/perl -w

my $srceDir   = "/mnt/SDrive/SV/Capture Data/";
my $startDate = "2013-02-14";
my $endDate   = "2013-02-15";

use strict;
use File::Find ();
use POSIX qw|mktime|;

use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

my ($sDay,$eDay)=map {
    my ($year,$month,$day)=split("-",$_);
    (time()-mktime(0,0,0,$day,$month-1,$year-1900))/86400
} ($startDate,$endDate);

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);

    (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
    -f _ &&
    (-M _ < $sDay) &&
    ! (-M _ < $eDay)
    && print("$name\n");
}
File::Find::find({wanted => \&wanted}, $srceDir );

これの最大の利点は、open $fh,"find ...|"非常に強力であることです。ファイル名の文字(スペース、引用符、アンパサンドなど)に気を付ける必要はありません。

おすすめ記事