2011-04-29 132 views
-4

我需要編寫一個perl程序來接受命令行參數,這些命令行參數可以連接成 perl解析命令行參數

myPerl.pl -l -c -d same as myPerl.pl -lcd 

唯一的約束是,我不能如「getopts的」,誰知道什麼我可以做輕鬆地實現這個使用構建模塊。

+8

爲什麼你不能使用模塊?他們的目的是爲了解決這些問題,爲什麼重新發明車輪? – 2011-04-29 21:38:38

+5

除非這是一項家庭作業,否則您應該使用[Getopt :: Long](http://search.cpan.org/perldoc?Getopt::Long)或類似的模塊。 Getopt :: Long是核心Perl發行版的一部分,所以它幾乎保證可用。 – cjm 2011-04-29 21:49:09

+2

這是作業。 – darch 2011-04-30 00:19:14

回答

1

我同意,你應該使用模塊。總之,這裏的一個嘗試,你可以建立在:

use strict; 
use warnings; 
my @opts = grep /^-\w+/, @ARGV; 
print "(1) @opts\n" if @opts; 
my @normalized = sort grep /\w/, map { split /(-|)/ } @opts; 
print "(2) @normalized\n" if @normalized; 
+0

這太酷了。如果你可以解釋一下你的'@ normalized'部分,這對我像我這樣的初學者來說有點深刻。但無論如何,非常感謝,這太棒了。 – user685275 2011-04-29 22:16:01

+0

好吧,'@ normalized'是處理步驟的流水線。從右到左閱讀。首先,'@ opts'可以有'-x'或者'-yyy'之類的東西。我們希望將所有內容標準化爲'x'或'y',因爲我們可以統一處理它。我們使用'split'來分割'-'或空字符串。這個'split'的返回值是單個字母或空字符串的列表。我們使用'map'將這個操作應用到每個元素。我們使用'grep'來過濾掉空的字符串。然後我們對它進行分類,只是爲了整潔。然後我們稱之爲「@標準化」。 - 不過,考慮使用標準模塊來處理這種事情。 – Lumi 2011-04-30 08:55:24

2

這是不容易可靠地分析論證,這就是爲什麼有在Getopts::*列表(其中,在此背景下,無數≈180)無數的模塊。有很多可能的約定來處理。在顯示的示例命令行中,如果將最後一個參數(-lcd)視爲選項或像'same','as','myPerl.pl'參數可能是? 「相同」是-d選項的參數,還是單獨的「文件名」選項?單字母選項可以分組嗎?參數可以附加到選項嗎?他們必須被連接?他們必須分開嗎?你有多字母選項還是隻有單字母選項?

在您定義了諸如這些問題以及如何處理和處理這些問題之前,您無法開始編寫代碼來完成體面的工作。

您可能會發現答案使用這些問題:Bundling

+0

感謝您的回答,非常感謝。 – user685275 2011-04-29 22:13:58

10

Getopt::Long

更新:哦,沒有模塊。這是作業。那麼,將代碼從Getopt :: Long中複製出來。

+3

+1代表「將Getopt :: Long代碼複製出來」 – DVK 2011-04-30 07:08:30

4

模塊? 真的嗎?這就像那麼 perl4。 :)

那好吧,所以這裏是我們如何始終做到了在Perl4樣式:

ARG: while (@ARGV && $ARGV[0] =~ s/^-(?=.)//) { 
OPT: for (shift @ARGV) { 

      m/^$/  && do {         next ARG; }; 
      m/^-$/  && do {         last ARG; }; 

      s/^0//  && do { $nullpaths++;     redo OPT; }; 
      s/^f//  && do { $force++;      redo OPT; }; 
      s/^l//  && do { $reslinking++;     redo OPT; }; 
      s/^I//  && do { $inspect++;      redo OPT; }; 
      s/^i//  && do { $careful++;      redo OPT; }; 
      s/^v//  && do { $verbose++;      redo OPT; }; 
      s/^V//  && do { $verbose += 2;     redo OPT; }; # like two -v's 
      s/^m//  && do { $renaming++;     redo OPT; }; 
      s/^n//  && do { $nonono++;      redo OPT; }; 
      s/^N//  && do { $nonono += 2;     redo OPT; }; # like two -n's 
      s/^q//  && do { $quiet++;      redo OPT; }; 

      s/^F(.*)//s && do { push @flist, $1 || shift @ARGV; redo OPT; }; 

      &usage("Unknown option: $_"); 
     } 
    } 

是不是膨脹? :)

同樣的方法今天仍然有效,但它可能讓你談論。