【问题标题】:Best way to check if argument is a filename or a file containing a list of filenames?检查参数是文件名还是包含文件名列表的文件的最佳方法?
【发布时间】:2011-08-25 09:01:40
【问题描述】:

我正在编写一个 Perl 脚本,我想要一种方法让用户输入一个文件或包含 $ARGV[0] 中文件列表的文件。

我目前的做法是检查文件名是否以@开头,如果是,则将该文件视为文件名列表。

这绝对不是理想的方法,因为我注意到@ 是 bash 中的一个特殊字符(顺便说一句,它有什么作用?我只在 bash 中的 $@ 中看到过它)。

【问题讨论】:

  • '@' 字符对于 shell 来说不是特殊的。它只是特殊参数名称之一,就像'?'在'$?'用于最后一个命令的退出状态。这就是为什么您会看到它专门用作“$@”的原因。在所有其他情况下,shell 没有赋予它任何意义。特别是您可以将其用作文件名中的第一个字符。
  • 读取文件的第一行并检查它是否是有效的文件名?

标签: linux perl unix


【解决方案1】:

您可以在命令行上指定其他参数以区别对待它,例如

perl script.pl file

用于读取文件的内容,或

perl script.pl -l file

用于从 file 中读取文件列表。

您可以使用getopt 模块来更轻松地解析输入参数。

【讨论】:

  • 绝对是个好主意。这就是 wget 所做的,例如 - wget urlwget -i file-containing-list-of-urls
  • 我推荐Getopt::Long 而不是Getopt::Std。它几乎完成了 Getopt::Std 所做的所有事情,还有更多(特别是像 -list file 这样的长选项名称。)
  • 我目前正在使用 Getopt::Long 作为脚本中的其他选项。我在这个环境中编写所有脚本,第一个参数作为裸文件名,这就是我想要这个功能的原因。我想按照我的方式来做,我将不得不选择另一个不常见的字符,一个不会在制表符完成时自动转义的字符。
  • 我不太确定您所说的“使用 Getopt::Long 来获取脚本中的其他选项”是什么意思,但可以移开 @ARGV 的第一个元素并使用Getopt::Long 在剩余的参数上,所以你的电话是:perl script.pl file -l。这行得通吗?
【解决方案2】:

首先,您可以使用 shell 为您获取列表:

perl script.pl <( cat list )

如果您不想这样做,可能是因为您正在运行最大命令行长度,您可以在使用@ARGVARGV(包括&lt;&gt;)之前使用以下内容:

@ARGV = map {
   if (my $qfn = /^\@(.*)/s) {
      if (!open(my $fh, '<', $qfn)) {
          chomp( my @args = <$fh> );
          @args
      } else {
          warn("Can't open $qfn: $!\n");
          ()
      }
   } else {
      $_
   }
} @ARGV;

请记住,如果您的文件名称以“@”开头,则会产生意想不到的副作用。

【讨论】:

    【解决方案3】:

    '@'Perl 中是特殊的,因此您需要在 Perl 字符串中对其进行转义——除非您使用 'a non-interpolating $string'非插值 字符串类型或q(another non-interpolating $string) 或者你需要转义它,像这样

    if ( $arg =~ /^\@/ ) {
        ...
    }
    

    插值分隔符是以下任何一种:

    • "..."qq/.../
    • `...`qx/.../
    • /.../qr/.../

    对于所有这些,您必须转义任何文字 @

    否则,以@ 开头的文件名在命令行参数中具有很好的优先级。

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2016-02-04
      • 2015-09-14
      • 1970-01-01
      相关资源
      最近更新 更多