我正在寫一個Perl腳本,我想要一種方法讓用戶輸入一個文件或一個包含$ ARGV [0]中文件列表的文件。檢查參數是文件名還是包含文件名列表的文件的最佳方法?
我現在這樣做的方式是檢查文件名是否以@開始,如果是,那麼我將該文件視爲文件名列表。
這絕對不是理想的做法,因爲我注意到@是bash中的一個特殊字符(它是怎麼做的?我只在bash中看到它在$ @中使用) 。
我正在寫一個Perl腳本,我想要一種方法讓用戶輸入一個文件或一個包含$ ARGV [0]中文件列表的文件。檢查參數是文件名還是包含文件名列表的文件的最佳方法?
我現在這樣做的方式是檢查文件名是否以@開始,如果是,那麼我將該文件視爲文件名列表。
這絕對不是理想的做法,因爲我注意到@是bash中的一個特殊字符(它是怎麼做的?我只在bash中看到它在$ @中使用) 。
您可以在您的命令行上指定其他參數,以便對其進行不同的處理,例如,
perl script.pl file
閱讀文件的內容,或
perl script.pl -l file
從文件讀取文件的列表。
您可以使用getopt模塊更容易地解析輸入參數。
絕對是個好主意。這就是'wget'所做的,例如''wget url'或'wget -i file-containing-list-of-urls'。 –
我建議[Getopt :: Long](http://perldoc.perl.org/Getopt/Long.html)而不是[Getopt :: Std](http://perldoc.perl.org/Getopt/Std.html )。它幾乎做了Getopt :: Std所做的一切,還有更多的東西(特別是很長的選項名稱,如'-list file')。 –
我目前正在使用Getopt :: Long作爲腳本中的其他選項。我在第一個參數中將所有的腳本寫在這個環境中作爲一個裸文件名,這就是爲什麼我需要這個功能。我想這樣做我不得不選擇另一個uncommon的角色,一個在選項卡完成時不會自動轉義的角色。 – OregonTrail
'@'
是Perl中特殊,所以你需要逃避它在你的Perl語句 - 除非你使用非插字符串類型的'a non-interpolating $string'
或q(another non-interpolating $string)
或者你需要逃避它,像這樣
if ($arg =~ /^\@/) {
...
}
插值定界符是以下任何一種:
"..."
或qq/.../
`...`
或qx/.../
/.../
或qr/.../
對於所有這些,你將不得不逃避任何文字@
。
否則,以@
開頭的文件名在命令行參數中具有相當不錯的優先級。
首先,你可以使用你的shell來獲取列表你:因爲你是對的最大命令行長度運行
perl script.pl <(cat list)
如果你不想這樣做,或許,你可以使用使用前@ARGV
或ARGV
(包括<>
)如下:
@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;
請記住,你就會有意想不到的副作用,如果您有其名稱以開頭的文件中「@」。
'@'字符不是特殊的外殼。它只是一個特殊的參數名稱,就像'?'在'$?'中爲最後一個命令的退出狀態。這就是爲什麼你會看到它被專門用作'$ @'的原因。在所有其他情況下,shell並沒有給出任何意義。特別是你可以使用它作爲文件名中的第一個字符。 – Jens
讀取文件的第一行並檢查它是否是有效的文件名? – flies