2017-10-05 5 views
3

母音を受け取り、その母音の出現数をテキストファイル "abc.txt"の中に表示するシェルスクリプトを作りたかったのです。grep文がcase文の中で動作しない

次のスクリプトは、完全に(母音の出現回数を印刷するためのスクリプト「」テキストファイル内の「abc.txt」)作品:

#!/bin/bash 
grep -o [aA] abc.txt|wc -l 

をしかし、私はすべてのためにこれを実装します母音はので、私はこれをしなかった:

#!/bin/bash 
echo -n "Enter the desired vowel: " 
read ch 
case ch in 
a) grep -o [aA] abc.txt|wc -l;; 
A) grep -o [aA] abc.txt|wc -l;; 
e) grep -o [eE] abc.txt|wc -l;; 
. 
. 
. 
U) grep -o [uU] abc.txt|wc -l;; 
esac 

コードが実行されるが、私は何も表示されない希望母音を入力した後。また、私はこれを試してみた(が、結果は上記のコードのものと同じです):私はcase内にそれらを置くときgrep文は何も表示されない理由として失われてい

#!/bin/bash 
x=0 
echo -n "Enter the desired vowel: " 
read ch 
case ch in 
a) x=grep -o [aA] abc.txt|wc -l;echo $x;; 
A) x=grep -o [aA] abc.txt|wc -l;echo $x;; 
e) x=grep -o [eE] abc.txt|wc -l;echo $x;; 
. 
. 
. 
U) x=grep -o [uU] abc.txt|wc -l;echo $x;; 
esac 

ステートメント。

答えて

3

複数の問題がありますが、主に問題の原因となっているのは、case構造の変数を使用していないためです。使用chは単なる定数であり、以下の式と一致しません。

case "$ch" in 
# ^^^^^ This needs to be a variable used in read command 

はまた、コマンドの出力を保存するために、あなたはタイプ$(cmd)のコマンド置換構文を使用する必要があります。 grep .. | wc -lの代わりに-cフラグを使用して、一致する文字列の合計数を返すこともできます。

x=$(grep -oc '[aA]' abc.txt); echo "$x" 

(または)さえ改善grepコマンドは-iフラグと大文字と小文字を区別しないマッチングを有効にするだろう

x=$(grep -oci 'a' abc.txt); echo "$x" 
+1

コマンドを改善したい場合は、vovelを検証する必要がない場合、 '' grep -oci "$ vovel" ''(大文字と小文字を区別しないgrep)を試してみてください。 – allo

+0

grep -oc [aA] abc.txtとgrep -oci 'a' abc.txtは動作していないようです。どちらも、存在するaの数にかかわらず、どちらも1を返します。 – Jaspreet

+0

@ Jaspreet:それは私のためにうまくいきます。あなたは私たち 'abc.txt'とどのようなコマンド文字表示することができますが – Inian

1

あなたの問題はcase文ではありませんが、変数を使用していることあなたはとして、-o [aA] abc.txtを実行するための変数xにgrepを代入している

x=grep -o [aA] abc.txt|wc -l;echo $x 

間違った方法での割り当ては、実行する変数を単にcommandに割り当てます。

これは当然意味をなさないですが、ファイルを削除したx=something rm *のようなものを試していないことをうれしく思います。

正しい構文はサブシェルでgrep|wcを実行し、変数xに結果を割り当てる手段

x="`grep -o '[aA]' abc.txt|wc -l`" 

あります。 x=""は完全に問題ありませんが、x=は構文エラーですので、コマンドに何も返されないときに引用符を付けずに問題が発生するので、引用符を追加しました。 bashで

あなたは同じことを行います(入れ子にすることができます)素敵な構文

x="$(grep -o '[aA]' abc.txt|wc -l)" 

を持っています。しかし、#!/bin/bashでスクリプトを開始してください。/bin/shは、構文がうまくいかないbash以外のシェルであることがよくあります。

fully POSIX compatible shellはすべて/bin/shで動作するはずですが、/bin/shは完全に互換性がない可能性がありますので、特定のシェルを使用するのは良い考えです。

+0

'$(...)'は 'bash'に固有のものではありません。これは、POSIX準拠のシェルでのコマンド置換に適した構文です。 – chepner

+0

ありがとうございます、私はそれを答えに加え、関連する答えをリンクしました。 – allo

1

オプションは「ch」なので、実行される行はありません。 "$ ch"を使用してケースに一致するものを入れると、 "grep"がxに割り当てられてから-oを実行しようとしたときにエラーが発生する可能性があります。

他の人はすでにx="$(grep ...)"のような構文を使用する必要があると説明しているだけでなく、文字セットの周りの引用符の必要性についても説明しています。 :)

grepを使用する場合は、大文字と小文字を区別しない一致のために文字クラスの代わりに-iを試してください。

可能であれば、できるだけコードを単純化するために、実際の問題のロジックを再構成してみてください。

echo -n "Enter the desired vowel: " 
read ch 
grep -io "$ch" abc.txt | wc -l 

これは、ケースステートメントをまったく必要としないか、カウントを出力するために別のエコーを必要とします。 case文が必要であると判断した場合は、コードを単純化して冗長性を減らすと便利なことがあります。

#!/bin/bash 
typeset -l ch # forces value to lowercase to make case easier 
file=abc.txt # used more than once, so put in a var to ease maintenance 
echo -n "Enter the desired vowel: " 
read ch  # will be lowercase no matter what they enter 
case "$ch" in # so we only have to match lower cases 
[aeiou]) grep -io "$ch" | wc -l ;; # reads stdin, writes to stdout 
*) echo "That's not a valid vowel" >&2 # write to STDERR to keep separate 
    exit 1 ;;       # handle invalid inputs 
esac < $file > match.count # all case I/O managed in one place here 
echo "There are $(<match.count) $ch's in $file" 

ところで、私は実際にマッチした行ではなくoccurrancesカウントするwc -l-oの使用を好みます。私はgrep-cを提案して、もう一度見えるまで余分なコマンドを削除しました。ニース。 :)