如何使用Perl创建目录并通过FTP将文件提取到该目录中?

时间:2010-05-25 08:16:03

标签: perl

我有一个看起来像这样的文件:

ftp://url1/files1.tar.gz dir1
ftp://url2/files2.txt dir2
.... many more...

我想要做的是这些步骤:

  1. 根据第2列创建目录
  2. Unix'cd'到该目录
  3. 使用基于column1的“wget”下载文件
  4. 但是我的这种方法怎么会起作用

    while(<>) {
      chomp;
      my ($url,$dir) = split(/\t/,$_);
      system("mkdir $dir");
      system("cd $dir");   
      system("wget $url"); # This doesn't get executed
    }
    

    这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:13)

尽可能使用原生Perl解决方案:

  • cd可以使用chdir
  • 完成
  • mkdir可以使用mkdir
  • 完成
  • mkdir -p(如果dir存在则不会死,递归创建)可以使用Perl附带的File::Path来完成
  • wget可以使用LWP::Simple
  • 完成

我将如何实现这一点:

use File::Spec::Functions qw(catfile);  # adds a '/' between things (or '\' on Windows)
use LWP::Simple qw(mirror);
use File::Path qw(mkpath);
use File::Basename;
use URI;

while (<>) {
    chomp;
    my ($url, $dir) = split /\t/;
    mkpath($dir);

    # Use the 'filename' of the $url to save 
    my $file = basename(URI->new($url)->path);
    mirror($url, catfile($dir, $file));
}

如果你这样做,你会得到:

  • 平台之间的可移植性
  • 炮弹之间的便携性
  • Perl异常处理(通过返回值或die
  • Perl输入/输出(无需转义任何内容)
  • 未来的灵活性(如果您更改计算文件名的方式,或者如何存储Web内容,或者您​​想并行运行Web请求)

答案 1 :(得分:4)

我会告诉你一个错误。 system("cd $dir");将创建一个子shell,切换到目录中的子shell,然后退出。

运行Perl的进程仍然在其原始目录中。

我不确定这是否是您的具体问题,因为# Fail here对细节有点了解: - )

一种可能的解决方法是:

system("mkdir $dir && cd $dir && wget $url");

这将在一个子shell中完成所有操作,因此不应该遇到上述问题。


实际上,这个脚本运行正常:

use strict;
use warnings;
system ("mkdir qwert && cd qwert && pwd && cd .. && rmdir qwert");

输出:

/home/pax/qwert