2011-10-24 190 views
3

所以我創建了下面這個腳本來完成一個任務,它需要一個文本文件並檢查單詞的頻率並列出出現次數最多的10個單詞。一切工作正常,但我需要此腳本能夠通過命令行以及通過標準輸入啓動。Perl - 命令行輸入&STDIN

所以我需要能夠寫'perl wfreq.pl example.txt',並且應該啓動腳本並且不要提問文本文件。我不確定如何實現這一點,我想我可能需要一個while循環,在開始的某個地方跳過STDIN,如果你在終端命令行給它的文本文件。

任何人都可以提供幫助嗎?

#! /usr/bin/perl 

use utf8; 
use warnings; 

print "Please enter the name of the file: \n" ; 
$file = <STDIN>; 
chop $file; 


open(my $DATA, "<:utf8", $file) or die "Oops!!: $!"; 
binmode STDOUT, ":utf8"; 

while(<$DATA>) {       
    tr/A-Za-z//cs; 
    s/[;:()".,!?]/ /gio;     
    foreach $word (split(' ', lc $_)) { 
    $freq{$word}++;     
    } 
} 
foreach $word (sort { $freq{$b} <=> $freq{$a} } keys %freq) {   
    @fr = (@fr, $freq{$word}); 
    @ord = (@ord, $word);   
} 
for ($v =0; $v < 10; $v++){ 
print " $fr[$v] | $ord[$v]\n"; 
} 

回答

5

您可以閱讀STDIN僅如果不提供文件名:

my $DATA; 
my $filename = $ARGV[0]; 
if ($filename) { 
    open($DATA, $filename) or die $!; 
} else { 
    $DATA = STDIN; 
} 

好吧,我誤解了這個問題,根據您的評論,你需要做到以下幾點:

my $DATA; 
my $filename = $ARGV[0]; 
unless ($filename) { 
    print "Enter filename:\n"; 
    $filename = <STDIN>; 
    chomp $filename; 
} 
open($DATA, $filename) or die $!; 

雖然我有說,用戶提示是非常unix像。

+0

這很好,看起來像我想要的。 my $ DATA; my $ file = $ ARGV [0];如果($ file){0}打開($ DATA,$ file)或$ $!其他{ print「請輸入文件的名稱:\ n」; $ DATA = STDIN; } 我現在可以通過命令行arg來啓動它,但是當我沒有啓動它時,它只會請求文件,但從不會通過腳本的其餘部分執行排序和打印。 (與「perl wfreq2.pl example.txt」一起使用,但在使用「perl wfreq2.pl」時不能使用) – FictionFighter

+0

不確定我在做什麼錯,但是我不能在剛開始時聲明「perl wfreq.pl「它確實要求該文件是一個STDIN,但它並沒有移動,並進行實際的排序和列表。 – FictionFighter

+0

好吧,我更新了我的答案,我誤解了你的問題。 – 2011-10-24 10:21:27

0

你可以做的是爲您在@ARGV命令行參數,這是Perl的數組,它自動地抓住了命令行參數,以及 - 如果有的話 - 處理這些(與其他輸入繼續從STDIN)。喜歡的東西:

use utf8; 
use strict; #Don't ever forget this! Always, always, ALWAYS use strict! 
use warnings; 

if(@ARGV) 
{ 
    #Assume that the first command line argument is a file to be processed as in your original code. 
    #You may or may not want to care if additional command line arguments are passed. Up to you. 
} 
else 
{ 
    #Ask for the filename and proceed as normal. 
} 

請注意,您可能希望將代碼隔離處理的文件名(即DATA開幕,通過線去,計算的話,等),以一個子程序,你可以輕鬆地調用(也許有一個由文件名組成的參數)在代碼的每個分支中。

哦,以確保我清楚這一點:總是use strict總是use warnings。如果你不這樣做,那你就是在尋求麻煩。

+0

謝謝,我會閱讀@ARGV,看看我能做些什麼。 – FictionFighter

0
perl script.pl < input.txt 

使用<input.txt傳遞到script.pl作爲標準輸入操作者。然後您可以跳過查詢文件名。否則,使用$ARGV[0]或類似的,如果defined

+0

這隻會給我錯誤消息。 adm @ adm-desktop:〜/ Desktop/perl $ perl wfreq2.pl 第1行。 – FictionFighter

+0

正如我所說的,跳過查詢文件名,只是在'while'循環中循環<<>。 –

+0

'input.txt'中是否有其他文件(即另一個文件的名稱)? – 2011-10-24 09:36:05

7

而不是從<STDIN>讀取,您可以從<>讀取從命令行提供的文件或如果沒有文件從標準輸入獲取數據。

例如,與該程序:

#!/usr/bin/env perl 

while (<>) { 
    print $_; 
} 

命令./script foo.txtfoo.txt將讀取並打印行,而./script本身將讀取並從stdin打印行。