2014-10-22 58 views
1

我正在研究一個學校項目,該項目涉及到一個主要的shell腳本,它將提示用戶輸入一個包含50個單詞的文本文件。如果shell腳本在與shell和perl腳本相同的目錄中找到該文件,它將打印一個菜單,詢問用戶是否想要使用shell對列表進行排序,並將排序後的列表輸出到新文件(該文件已完成和作品),調用perl腳本,perl腳本將在那裏獲取該文件並打印該文件中的所有單詞,然後提示用戶輸入他們想要搜索的單詞。這將返回列表中該單詞的哪一行。我所做的是,如果用戶選擇使用perl腳本進行排序,我們將輸入的文件在shell中通過管道傳遞給perl腳本:在從shell腳本將文件傳輸到perl腳本之後詢問其他輸入

cat $ filename | ./search.pl

恰好成功將文件傳輸到我們可以使用它的perl腳本。第一個while循環是我們訪問列表並打印每個單詞/行以供用戶查看的地方,它可以正常工作。 但這是我遇到麻煩的地方。在打印完整個列表之後,要求輸入他們要搜索的單詞的printf行將會打印,但是程序會停止而不允許再輸入,然後返回到終端。我對這個搜索腳本的邏輯是,我們爲用戶打印每個單詞以查看他們可以搜索的內容,然後詢問他們想要搜索的內容,然後在shell腳本中查看輸入的文件,循環;如果我們找到它,打印出我們發現它的那一行,如果我們沒有找到它,那麼轉到下一行,如果我們發現它沒有找到它,只是打印它找不到它。

爲什麼我無法輸入更多的輸入與調用STDIN並將其分配給$ word在第二個while循環中使用?此外,當我正在做第二個while循環時,在請求不同的輸出會讓事情變得糟糕之後,它本身正在使用<>如果是這樣,我如何再次對第二個while循環的文件進行引用?

#!/usr/bin/env perl 

$count = 1; #global variable for return value 
       # of words. 

while (<>) { 
    printf "$_"; 
} 
#Now that we have opened the file, printed off everything for the user to see, they can now enter a  word in a prompt to 
# see what line it is on. 

printf "\nPlease enter the word you want to search for\n"; 
my $word = <STDIN>; 
chomp $word; 

while ($line = <>) { 
    if ($line =~ m/$word/) { 
     print "$word has been found on line $count.\n\n"; 
    } elsif ($line !=~ m/$word/) { 
     $count++; 
    } else { 
     print "$word cannot be found."; 
    } 
} 

殼牌腳本(供參考):

#!/bin/bash 

clear 
printf "Hello. \nPlease input a filename for a file containing a list of words you would like to use.  Please allow for one word per line.\n -> " 
read filename 
printf "You have entered the filename: $filename.\n" 

if [ -f "$filename" ] #check if the file even exists in the current directory to use 
then 
    printf "The file $filename exists. What would you like to do with this file?\n\n" 
else 
    printf "The file: $filename, does not exist. Rerun this shell script and please enter a valid file with it's proper file extension. An example of this would be mywords.txt \n\nNow exiting.\n\n" 
    exit 
fi 

printf "Main Menu\n" 
printf "=========\n" 
printf "Select 1 to sort file using Shell and output to a new file.\n" 
printf "Select 2 to sort file using Perl and output to a new file.\n" 
printf "Select 3 to search for a word using Perl.\n" 
printf "Select 4 to exit.\n\n" 

echo "Please enter your selection below" 
read selection 
printf "You have selected option $selection.\n" 

if [ $selection -eq "1" ] 
then 
    read -p "What would you like to call the new file? " newfile #asks user what they want to call the new file that will have the sorted list outputted to it 
    sort $filename > $newfile 
    echo "Your file: $newfile, has been created." 
fi 

if [ $selection -eq "2" ] 
then 
    read -p "What would you like to call the new file? " newfile2 
    cat $filename | ./sort.pl 
    # > $newfile2 #put the sorted list into the new output file that the user specificed with newfile2 
fi 

if [ $selection -eq "3" ] 
then 
    cat $filename | ./search.pl 
fi 

if [ $selection -eq "4" ] 
then 
    printf "Now exiting.\n\n" 
    exit 
fi 
+0

你首先需要的是'使用嚴格的; 使用警告;'在文件頂部。我認爲你的問題是,當你第二次通過時,'<>'是文件結尾。一個更好的解決方案是讀取文件一次,並把它放入一個數組,然後通過數組看看 – KeepCalmAndCarryOn 2014-10-22 05:45:35

+0

這將解釋爲什麼它會一直試圖在STDIN和STDIN中放入第二個while循環,甚至沒有運行... – ThomasM 2014-10-22 17:46:56

+0

即使我把它放入一個數組中,我仍然遇到這個問題,我要求STDIN提供這個單詞,它仍然會嘗試將EOF放入它。 – ThomasM 2014-10-22 17:58:33

回答

0

我已經修改您的代碼如下所示。爲了您的理解,我一直在發表評論,但儘量避免在不需要的地方發表評論。

代碼:

#!/usr/bin/env perl  
use strict; 
use warnings; 

#Input File passing as an argument to the program 
my $InFile = $ARGV[0]; 

#Opening and reading a file using filehandle $fh 
open my $fh,'<', $InFile or die "Couldn't open the file $InFile : $!"; 

while (<$fh>) { 
    printf "$_";   
} 

# Seek function as shown below will reset the file handle position to beginning of the file 
seek($fh, 0, 0); 
printf "\nPlease enter the word you want to search for\n"; 
my $word = <STDIN>; 
chomp $word; 
my $count = 1; #global variable for return value of words    
my $val = 0; 

while (my $line = <$fh>) { 
    if ($line =~ m/$word/) { 
     print "$word has been found on line $count.\n\n"; 
     $val++; 
    } 
    elsif ($line !~ m/$word/) { 
     $count++; 
    } 
} 
if ($val == 0) { 
    print "$word cannot be found"; 
} 

close($fh); 
+0

我試過你的方法,它在我們打開$ fh的行上有問題。 使用未初始化的值$ InFile打開./search.pl第40行。 使用未初始化的值$ InFile連接(。)或字符串位於./search.pl第40行。 無法打開文件:在./search.pl第40行沒有這樣的文件或目錄。 我以爲它在$ InFile將列表傳遞給它時被初始化。 – ThomasM 2014-10-22 18:08:08

+0

你能告訴我你正在嘗試訪問的輸入文件名嗎? – Praveen 2014-10-22 18:20:20

+0

當你運行程序的時候,給出如下所示:perl filename.pl inputfilename。你懂我的意思了嗎 ? – Praveen 2014-10-22 18:25:28