perl -n来自管道和@ARGV的输入

时间:2012-06-08 07:51:46

标签: perl command-line-arguments

我有这样的单行:

date +%H | perl -ne 'printf "%02d", $_ - ($ARGV[0] - 1);' 1

它说:

Can't open 1: Datei oder Verzeichnis nicht gefunden.

错误消息表示“找不到文件或目录”。

我希望它同时从date和commandline参数中获取输出。

基本上它应该让我当前小时减去参数减一。如果有更好的方法来实现这一目标,我会很乐意接受它们。我仍然很感激解释为什么这不起作用。

我们假设它现在是在上午10点之后。

Param Output
    1     10
    2     09
    3     08

2 个答案:

答案 0 :(得分:2)

结果可能是昨天,甚至是过去的结果,只打印一小时没有多大意义。

perl -mDateTime -e'
    my $dt = DateTime->now;
    $dt->subtract(hours => 1);
    $dt->subtract(hours => shift @ARGV);
    print $dt->hour;
' 4

尽可能使用标准的日期时间戳,例如广泛使用的RFC3339。

perl -mDateTime -mDateTime::Format::RFC3339 -e'
    my $dt = DateTime->now;
    $dt->subtract(hours => 1);
    $dt->subtract(hours => shift @ARGV);
    print DateTime::Format::RFC3339->new->format_datetime($dt);
' 4

你的Perl单行代表:

LINE: while (defined($_ = <ARGV>)) {
    printf '%02d', $_ - ($ARGV[0] - 1);
}

...因为-nARGV

  

在@ARGV中迭代命令行文件名的特殊文件句柄。

但是你没有文件名作为参数。

答案 1 :(得分:2)

perl -n创建一个隐式循环读取文件,列为参数或STDIN,如果没有参数;这与你对不同事物的论证的使用相冲突。您可以通过清除BEGIN块中的@ARGV来解决此问题:

date +%H | perl -ne 'BEGIN{ $arg=shift } printf "%02d", $_ - ($arg - 1);' 1

但是对于这个特殊的任务,你最好还是完全在perl中进行日期计算。