長くて混乱していたらすみません。cat
、、、dog
という3つのファイルがあります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
しかし、同時に3つのファイルをすべて実行したい場合はどうすればよいですか?
次のように表示したいとします。
Enter file name : cat dog cow
5 cat
2 dog
14 cow
Total 21
残念ながら
file not found
すべてのファイルを同時に実行しましたが、ファイルごとにスクリプトを1つずつ実行してみると問題はありません。
ベストアンサー1
コメントですでに述べた構文の問題に加えて、コードの主な問題は、複数のファイル名を単一の文字列として読み取った後、その単一の文字列を単一のファイル名として使用することです。
スクリプトのこれらの側面を変更する代わりに、やりたいことをもう一度考えてみましょう。
ユーザーに 1 つ以上のファイル名を指定させ、スクリプトに各ファイルの行数を計算し、各ファイルの行数と総行数を出力させたいとします。また、ユーザーがこの情報を出力ファイルに保存できるようにしたいと思います。ファイル名が存在しない場合は、ユーザーに通知したいと思います。
スクリプトは次のとおりです。
#!/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
ユーティリティは標準入力から読み始めるため、少し混乱する可能性があります。
いくつかの方法でこれを行うことができますが、ここではブーストスクリプトの2つのバリエーションを紹介します。
#!/bin/sh -
if [ "$#" -eq 0 ]; then
echo 'expected to get filename argument(s)' >&2
exit 1
fi
wc -l -- "$@"
$#
スクリプトが取得したコマンドライン引数の数である値を調べます。値が0の場合、ステートメントは診断メッセージを印刷してからスクリプトを終了する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)