2013-12-12 26 views
0

我有以下文件找到了最新的文件不同的路徑,但具有相同的文件名

./path/to/stuff1/file1 (x) 
./path/to/stuff1/file2 
./path/to/stuff1/file3 

./path/to/stuff2/file1 
./path/to/stuff2/file2 (x) 
./path/to/stuff2/file3 

./path/to/stuff3/file1 (x) 
./path/to/stuff3/file2 
./path/to/stuff3/file3 

,我標誌着我摸到最後的文件。我想要得到那些標記的文件。換句話說:

  • 我想向上最新文件每個目錄。

我構建的bash命令

for line in $(find . -name 'file*' -type f | awk -F/ 'sub($NF,x)' | sort | uniq); do 
     find $line -name 'file*' -type f -printf '%[email protected] %p\n' | sort -n | tail -1 | cut -f2 -d' ' 
done 

這我能夠在使用system命令並逃逸$ Perl來使用。是否有可能直接在Perl中執行此操作,或者您認爲我的方法是否正確?

編輯

如果可能的任務應該在Perl來完成,而無需使用外部模塊。

EDIT2

對不起,我發現我的問題不明確。我認爲@TLP的答案可行,但我必須澄清:我想檢查每個文件夾中的最新文件,例如最新的文件stuff1。說我做

touch ./path/to/stuff1/file1 
touch ./path/to/stuff2/file2 
touch ./path/to/stuff3/file1 

我運行腳本之前。那麼就應該輸出:

./path/to/stuff1/file1 
./path/to/stuff2/file2 
./path/to/stuff3/file1 

文件名可以是不同的東西但只有每個路徑的一個文件應該是輸出相同。

@codnodder腳本執行此操作,但我希望僅搜索文件名而不是完整路徑。所以我想搜索以文件開頭的所有文件,並且腳本應該遞歸搜索。

回答

1

您的find命令可以用File::Findfind命令來模擬。這是Perl 5中的核心模塊,幾乎可以肯定已經在您的系統中。要檢查文件修改時間,可以使用-M文件測試。

因此,像這樣:

use strict; 
use warnings; 
use File::Find; 

my %times; 
find(\&wanted, '.'); 
for my $dir (keys %times) { 
    print $times{$dir}{file}, "\n"; 
} 

sub wanted { 
    return unless (-f && /^file/); 
    my $mod = -M $_; 
    if (!defined($times{$File::Find::dir}) or 
     $mod < $times{$File::Find::dir}{mod}) { 
     $times{$File::Find::dir}{mod} = $mod; 
     $times{$File::Find::dir}{file} = $File::Find::name; 
    } 
} 

如果我在我的測試目錄中運行此命令,我的系統上,我得到以下Data::Dumper結構,在那裏你可以清楚地看到文件名鍵,完整路徑存儲在file密鑰中,修改日期(天數與腳本的運行時間相比)爲mod

$VAR1 = { 
      './phone' => { 
         'file' => './phone/file.txt', 
         'mod' => '3.47222222222222e-005' 
         }, 
      './foo' => { 
         'file' => './foo/fileb.txt', 
         'mod' => '0.185' 
        }, 
      '.' => { 
        'file' => './file.conf', 
        'mod' => '0.154490740740741' 
       } 
     }; 
+0

很抱歉的混亂,但我只注意到你的腳本不輸出期望的文件。我編輯了這個問題...... – EverythingRightPlace

+0

這只是改變目錄名稱的關鍵,而不是我現在所做的。 – TLP

+0

太棒了,thx很多! – EverythingRightPlace

1

有3種我能想到的一般方法。

  1. 使用opendir(),readdir()和stat()。
  2. 使用File :: Find。
  3. 使用glob()。

最合適的選擇取決於您的 要使用的具體細節,我們無法從您的發佈中看到。

此外,我假設當你說「沒有外部模塊」,你不是 排除與Perl(即在覈心)安裝的模塊。

下面是使用水珠()的例子:

use File::Basename qw/fileparse/; 

for my $file (newest_file()) { 
    print "$file\n"; 
} 

sub newest_file { 
    my %files; 
    for my $file (glob('./path/stuff*/file*')) { 
     my ($name, $path, $suffix) = fileparse($file); 
     my $mtime = (stat($file))[9]; 
     if (!exists $files{$path} || $mtime > $files{$path}[0]) { 
      $files{$path} = [$mtime, $name]; 
     } 
    } 
    return map { $files{$_}[1] } keys %files; 
} 
+0

對不起,忘了提及我正在使用Perl 5.10.1。是的,使用核心模塊沒有問題。 – EverythingRightPlace

+0

您的腳本也可以使用。我將一行改爲'$ files {$ path} = [$ mtime,「$ path $ name」];'這讓我獲得了所需的文件路徑輸出。希望接受這兩個答案,thx傢伙。 – EverythingRightPlace

相關問題