如何使用perl将文件从服务器移至计算机

时间:2018-08-24 17:53:17

标签: windows perl

我想将文件从Windows计算机所连接的服务器移至实际计算机。我已经在Mac上尝试了该代码,并且可以正常工作,因此我怀疑问题与我希望移动的文件位于服务器或Windows上有关(我不熟悉此操作系统)。能够使用File::Find::Rule对我来说很重要,因为子目录中有许多子目录需要搜索。

use strict;
use warnings;
use File::Find::Rule;
use File::Copy;

# directory where files live
# my $dir = "\\172.18\user\folder\folder2";

# directory where TextGrids will be moved to
my $outdir = "\users\lisa\desktop\test";

my @files;

@files = File::Find::Rule   -> file()
                             -> name("*_clean.TextGrid")
                             -> maxdepth()
                             -> in($dir);

foreach my $file (@files) {
    $file =~ /(.*\\)(.*)/;
    my $name = $2;
    copy("$file", "$outdir/$name") or die "Copy failed: $!";
    }

编辑:好的,我对下面的脚本做了一些更改。但是奇怪的是,当我要求它打印每个文件时,它给了我类似\\172.18\user\folder\folder/255/file.txt的东西。我将正则表达式更改为(.*\/)(.*),现在脚本可以完美运行,尽管我不知道为什么!

use strict;
use warnings;
use File::Find::Rule;
use File::Copy;

# directory where files live
my $dir = "\\\\172.18\\user\\folder\\folder2";

# directory where TextGrids will be moved to
my $outdir = "C:\\Users\\lisa\\desktop\\test";

my @files;

@files = File::Find::Rule   -> file()
                             -> name("*_clean.TextGrid")
                             -> maxdepth()
                             -> in($dir);

foreach my $file (@files) {
    print "$file\n";
    $file =~ /(.*\\)(.*)/;
    my $name = $2;
    copy("$file", "$outdir\\$name") or die "Copy failed: $!";
    }

2 个答案:

答案 0 :(得分:1)

编辑后,脚本起作用,因为字符串中的最后一个目录分隔符碰巧是/,它与正则表达式中的\/匹配。即使输入中包含\,用于查找文件的库仍添加了/


我有一些建议:

  1. 除非使用双引号引起来的插值,否则可以避免使用单引号引起来的转义(大多数)。

    转义反斜杠是可选的,除非后面加上单引号或另一个反斜杠:

    my $outdir = '\users\lisa\desktop\test';
    

    但是

    my $outdir = '\users\lisa\desktop\test\\';
    $outdir = '\users\lisa\desktop\test\\\'ere is a path';
    
    my $not_a_path = 'three backslashes\\\\\in between, all but the last need escaping';
    

    'ere is a path是该路径中的最后一个元素。

  2. 如果要使用Windows,请考虑在正则表达式中使用[\\/]代替目录分隔符。 (如果您绝对必须使用[\\\/]作为正则表达式定界符,则使用/。)

    即使您可以控制用户输入仅在路径中使用\,使用的库也通常会添加/,因此最好为两者的结合做好准备。

    $file =~ /(.*[\\\/])(.*)/;
    $file =~ m{(.*[\\/])(.*)};
    $file =~ m¤(.*[\\/])(.*)¤;
    

我还删除了$file调用中copy()周围多余的引号。最终结果:

use strict;
use warnings;
use File::Find::Rule;
use File::Copy;

# directory where files live
my $dir = '\\172.18\user\folder\folder2';

# directory where TextGrids will be moved to
my $outdir = 'C:\Users\lisa\desktop\test';

my @files;

@files = File::Find::Rule   -> file()
                            -> name("*_clean.TextGrid")
                            -> maxdepth()
                            -> in($dir);

foreach my $file (@files) {
    print "$file\n";
    $file =~ /(.*[\\\/])(.*)/;
    my $name = $2;
    copy($file, "$outdir\\$name") or die "Copy failed: $!";
}

答案 1 :(得分:0)

use strict;
use warnings;

my $dir = "\\172.18\user\folder\folder2";
print("$dir\n");

my $outdir = "\users\lisa\desktop\test";
print("$outdir\n");

输出

Unrecognized escape \d passed through at a.pl line 7.
\172.18Ser?older?older2
Sersisadesktop  est

您需要转义反斜杠!

use strict;
use warnings;

my $dir = "\\\\172.18\\user\\folder\\folder2";
print("$dir\n");

my $outdir = "\\users\\lisa\\desktop\\test";
print("$outdir\n");

不要忽略警告。