1

我是 perl noob,并尝试执行以下操作:

  1. 递归搜索目录中具有特定字符串的文件。说字符串是'abc.txt'
  2. 该文件可以位于两个不同的子目录中,例如 dir_1 或 dir_2
  3. 找到文件后,如果在 dir_1 中找到,则将其重命名为 dir_1_abc.txt。如果它在 dir_2 中,则将其重命名为 dir_2_abc.txt。
  4. 找到并重命名所有文件后,将它们全部移动到名为 dir_3 的新目录

我不在乎是否必须使用任何模块来完成此操作。我一直在尝试使用 File::Find::Rule 和 File::copy 来做到这一点,但没有得到想要的结果。这是我的示例代码:

#!/usr/bin/perl -sl
use strict;
use warnings;
use File::Find::Rule;
use File::Copy;

my $dir1 = '/Users/macuser/ParentDirectory/logs/dir_1'  
my $dir2 = '/Users/macuser/ParentDirectory/logs/dir_2'  

#ideally I just want to define one directory but because of the logic I am using in IF 
#statement, I am specifying two different directory paths

my $dest_dir = '/Users/macuser/dir_3';
my(@old_files) = find( 
              file => (),
              name => '*abc.txt', 
              in => $dir1, $dir2 ); #not sure if I can give two directories, works with on


foreach my $old_file(@old_files) {

        print $old_file;    #added this for debug

    if ($dest_dir =~ m/dir_1/)       
    {
      print "yes in the loop";
      rename ($old_file, "dir_1_$old_file");
          print $old_file;
          copy "$old_file", "$dest_dir";
    } 

       if ($dest_dir =~ m/dir_2/)       
   {
      print "yes in the loop";
      rename ($old_file, "dir_2_$old_file");
          print $old_file;
          copy "$old_file", "dest_dir";
   } 
   }

上面的代码不会更改文件名,而是当我在 if 中打印 $old_file 时,它​​会吐出找到文件的整个目录路径,并且分别在路径前加上 dir_1 和 dir_2。有什么大错特错。请简单地帮忙。

4

2 回答 2

0

如果文件可以在重命名时放置在目标中,请尝试以下操作:

#!/usr/bin/perl
use strict;

use File::Find;
use File::Copy;

my $dest_dir = '/Users/macuser/dir_3';
foreach my $dir ('/Users/macuser/ParentDirectory/logs/dir_1', '/Users/macuser/ParentDirectory/logs/dir_2') {
    my $prefix = $dir; $prefix =~ s/.*\///;

    find(sub {
        move($File::Find::name, "$dest_dir/${prefix}_$_") if /abc\.txt$/;
    }, $dir);
}

如果您需要先进行所有重命名然后将它们全部移动,您可以记住必须移动的文件列表,或者您可以进行两次传递,以确保在初始重命名后第二次传递的模式仍然可以第一次通过。

于 2013-09-26T02:17:51.067 回答
0

如果你有 bash (我假设它在 OSX 中可用),你可以用几行来完成(通常我把它们放在一行中)。

destdir="your_dest_dir"
for i in `find /Users/macuser/ParentDirectory/logs -type f -iname '*abc.txt'  ` 
do  
    prefix=`dirname $i`
    if [[ $prefix = *dir_1* ]] ; then
        prefix="dir_1"
    fi

    dest="$destdir/${prefix}_`basename $i`"
    mv "$i" "$dest" 
done

这种方法的优点是你可以有很多子目录logs,你不需要指定它们。您也可以搜索类似的blah_abc.txt文件tada_abc.txt。如果你想要一个完全匹配只是 juse abc.txt,而不是*abc.txt.

于 2013-09-26T02:34:49.990 回答