2011-08-24 66 views
2

我正在寫一個Perl腳本,我想要一種方法讓用戶輸入一個文件或一個包含$ ARGV [0]中文件列表的文件。檢查參數是文件名還是包含文件名列表的文件的最佳方法?

我現在這樣做的方式是檢查文件名是否以@開始,如果是,那麼我將該文件視爲文件名列表。

這絕對不是理想的做法,因爲我注意到@是bash中的一個特殊字符(它是怎麼做的?我只在bash中看到它在$ @中使用) 。

+0

'@'字符不是特殊的外殼。它只是一個特殊的參數名稱,就像'?'在'$?'中爲最後一個命令的退出狀態。這就是爲什麼你會看到它被專門用作'$ @'的原因。在所有其他情況下,shell並沒有給出任何意義。特別是你可以使用它作爲文件名中的第一個字符。 – Jens

+0

讀取文件的第一行並檢查它是否是有效的文件名? – flies

回答

5

您可以在您的命令行上指定其他參數,以便對其進行不同的處理,例如,

perl script.pl file 

閱讀文件的內容,或

perl script.pl -l file 

文件讀取文件的列表。

您可以使用getopt模塊更容易地解析輸入參數。

+2

絕對是個好主意。這就是'wget'所做的,例如''wget url'或'wget -i file-containing-list-of-urls'。 –

+4

我建議[Getopt :: Long](http://perldoc.perl.org/Getopt/Long.html)而不是[Getopt :: Std](http://perldoc.perl.org/Getopt/Std.html )。它幾乎做了Getopt :: Std所做的一切,還有更多的東西(特別是很長的選項名稱,如'-list file')。 –

+0

我目前正在使用Getopt :: Long作爲腳本中的其他選項。我在第一個參數中將所有的腳本寫在這個環境中作爲一個裸文件名,這就是爲什麼我需要這個功能。我想這樣做我不得不選擇另一個uncommon的角色,一個在選項卡完成時不會自動轉義的角色。 – OregonTrail

0

'@'Perl中特殊,所以你需要逃避它在你的Perl語句 - 除非你使用非插字符串類型的'a non-interpolating $string'q(another non-interpolating $string)或者你需要逃避它,像這樣

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

插值定界符是以下任何一種:

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

對於所有這些,你將不得不逃避任何文字@

否則,以@開頭的文件名在命令行參數中具有相當不錯的優先級。

1

首先,你可以使用你的shell來獲取列表你:因爲你是對的最大命令行長度運行

perl script.pl <(cat list) 

如果你不想這樣做,或許,你可以使用使用前@ARGVARGV(包括<>)如下:

@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; 

請記住,你就會有意想不到的副作用,如果您有其名稱以開頭的文件中「@」。

相關問題