【问题标题】:using perl fetch a .txt file and for every line in that file do something [duplicate]使用 perl 获取一个 .txt 文件,并为该文件中的每一行做一些事情[重复]
【发布时间】:2013-10-18 05:26:27
【问题描述】:

我是 perl 的新手,所以请试着理解我。 我在一个 .txt 文件中定义了一些这样的行:

doc1.20131010.zip
doc2.20131010.zip
doc3.20131010.zip
doc4.20131010.zip

我编写了这段代码:

#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use autodie;
use Net::SFTP::Attributes;
use Net::SFTP;
use constant {
    HOST            => "x.x.x.x",
    USER_NAME       => "sftptest",
    PASSWORD        => "**********",
    DEBUG           => "0",
};
my $REMOTE_DIR = "IN";
my $LOCAL_DIR  = "/home/rec";
my $sftp = Net::SFTP->new (
    HOST,
    timeout         => 240,
    user            => USER_NAME,
    password        => PASSWORD,
    autodie         => 1,
);

#
# Fetch Files
#
#my $res = $sftp->ls($REMOTE_DIR,sub { print $_[0]{longname}, "\n" });
#print "$res";
my $ls = $sftp->ls($REMOTE_DIR) 
    or die "ls failed: " . $sftp->error;
open my $fh, '>', '/home/rec/listing' or die "unable to create file: $!";
print $fh $_->{filename}, "\n" for @$ls;
close $fh;
open  F, "</home/docs/listing";
for my $line (<F>)
{
    #print "$line";
    $sftp->get("$line","$line") ;
}

现在当我运行上面的代码时,它应该给我上面列出的文件,而不是我得到这个:

Couldn't stat remote file: No such file or directory at ./r.pl line 40.

【问题讨论】:

  • 是的,但请告诉我更多信息,我不知道该看什么。谢谢
  • 我想告诉你,但不知道第40行的内容是什么
  • 我的错误内容是:$sftp->get("doc1.20131010.zip","doc1.20131010.zip");
  • 何时打印 "$line";我得到了我放在 .txt 中的文件列表,现在我想做同样的事情,但是这次使用 $sftp->get 列出所有来自 txt 的文件。谢谢
  • 我通过输入你的程序修改了你的帖子,这样更容易阅读。当我这样做时,我注意到你的程序只有 39 行。

标签: linux perl


【解决方案1】:

从文件句柄读取文件名后,您可能需要删除换行符:

for my $line (<F>) {
  chomp($line);
  $sftp->get($line, $line);
}

或更常见的是,

while (my $line = <F>) {
  chomp($line);
  $sftp->get($line, $line);
}

【讨论】:

  • 我还想问一件事。当我在远程 sftp 服务器中创建 ls 并在我的 .txt 中写入 ls 输出时,我得到了这个。 . doc1.20131010.zip .. doc3.20131010.zip doc3.20131010.zip doc4.20131010.zip 如何在脚本中告诉我忽略第一个点,然后忽略第三个两个点?谢谢。
  • ls -A 列出所有没有隐含的...
  • @mpapec 你能解释更多关于如何使用@$ls = grep !/^[.]{1,2}$/, @$ls; 以及这些行的位置吗?谢谢。
  • @user2866956 放在my $ls = .. 之后更正:@$ls = grep $_-&gt;{filename} !~ /^[.]{1,2}$/, @$ls;
  • @mpapec 谢谢,就是这样,现在一切都在完美运行。谢谢!
【解决方案2】:

你使用use autodie;,但你有:

open my $fh, '>', '/home/rec/listing' or die "unable to create file: $!";

不需要or die...,因为程序会自动终止。

您也有use feature qw(say);,但您使用print 而不是saysay 的全部目的是防止可能导致错误的问题。

您还应该检查$sftp-&gt;get($line, $line); 行的返回结果,看看它是否成功。

如果您同时执行了这两项操作,您会发现您的 $sftp-&gt;get($line, $line) 失败了,因为您忘记了文件末尾的 chomp 那个 NL。

您使用的是:

 `print $line;`

将文件打印出来,但由于文件名有 NL,所以看起来不错。否则,您会看到多余的空间并立即发现问题。

【讨论】:

  • 谢谢,我按照你说的修好了代码。效果很好!现在我需要找到一种方法来忽略这些点或根本不列出它们。
猜你喜欢
  • 2018-06-18
  • 2015-10-20
  • 2020-03-26
  • 1970-01-01
  • 2012-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
相关资源
最近更新 更多