問題處理多個文件,計算行數
對不起,如果它很長而且令人困惑,但我有三個文件,即
cat
,dog
和cow
.我的程式碼是這樣的:
echo -e "Enter file name: \c" read filename #saves variable if [ -e "$filename" ] then total =$(wc -l $filename) #calculate total lines in the*CAT* file echo There are $total #prints There are *numberoflines* echo $total > newfile #writes the answer into a newly created file else echo $filename not found fi
當我執行上面的程式碼時,會發生以下情況:
Enter file name : cat There are 5 cat
(我
cat
在提示符下輸入,我看到文件中的行數。)它會給我一個輸出,當我執行其中有 5 行的
5 cat
名為的文件時。cat
但是假設我想同時執行所有三個文件,我該怎麼辦?
假設我希望它顯示如下
Enter file name : cat dog cow 5 cat 2 dog 14 cow Total 21
不幸的是,它顯示
file not found
當我同時執行所有文件時,但如果我對文件逐個執行腳本,則沒有任何問題。
除了評論中已經提到的語法問題之外,您對程式碼的主要問題是您正在將您認為是多個文件名的內容讀入單個字元串,然後將該單個字元串用作單個文件名。
讓我們重新考慮一下您想要做什麼,而不是糾正腳本的那個方面。
您希望使用者提供一個或多個文件名,然後您希望腳本計算每個文件中的行數並輸出每個文件中的行數以及總行數。您還希望允許使用者將此資訊儲存到輸出文件中。如果文件名不存在,您希望使用者知道這一點。
腳本可能如下所示:
#!/bin/sh - wc -l -- "$@"
在不儲存輸出的情況下進行測試:
$ ./script.sh cat dog cow 5 cat 2 dog 14 cow 21 total
使用不存在的文件名呼叫腳本:
$ ./script.sh cat dog cow hamster 5 cat 2 dog 14 cow wc: hamster: No such file or directory 21 total
將輸出儲存在文件中:
$ ./script.sh cat dog cow hamster >output wc: hamster: No such file or directory
$ cat output 5 cat 2 dog 14 cow 21 total
腳本中的
"$@"
將替換為命令行參數列表,每個參數都單獨引用。這意味著如果您使用cat
,dog
和cow
在命令行上呼叫腳本,"$@"
腳本中的 將擴展至該列表。該
wc
實用程序已經執行了所有必要的操作,包括為您提供所有給定文件的總計,因此我們需要做的就是使用-l
腳本命令行上列出的文件名上的選項呼叫它,以使其計算行數.輸出預設寫入標準輸出。這使腳本的使用者可以自由地將輸出重定向到他們想要的任何地方。
另請注意,使用製表符完成或文件名通配模式為腳本提供命令行參數比在互動式提示下手動寫入每個文件名要方便得多。在這種情況下,它也大大簡化了腳本的程式碼。
您可能想要做的額外檢查是如果沒有提供任何文件名,則向使用者抱怨。否則該
wc
實用程序將從標準輸入開始讀取,這會有些混亂。您可以通過多種方式執行此操作,但我將在此處展示增強腳本的兩種變體:
#!/bin/sh - if [ "$#" -eq 0 ]; then echo 'expected to get filename argument(s)' >&2 exit 1 fi wc -l -- "$@"
這會查看
$#
值,即腳本獲得的命令行參數的數量。如果該值為零,則if
語句將分支到echo
,它將輸出診斷消息,然後終止腳本。#!/bin/sh - wc -l -- "${@?expected to get filename argument(s)}"
這做了類似的事情,但使用了非常不同的機制。如果為空或未設置,
${variable?word}
擴展將導致將診斷消息word
寫入輸出"$@"
,並且還將終止腳本。這可能看起來像:
$ ./script.sh ./script.sh[3]: @: expected to get filename argument(s)