在case语句中,grep语句不起作用

时间:2017-10-05 08:57:39

标签: linux bash shell sh

我想创建一个接受元音的shell脚本,并在文本文件“abc.txt”中打印该元音的出现次数。

以下脚本完美运行(用于打印文本文件“abc.txt”中元音“a”出现次数的脚本):

#!/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

代码执行但在我输入所需的元音后,没有显示任何内容。我也尝试了这个(但结果与上面的代码相同):

#!/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

当我将grep语句放入case语句中时,我很遗憾<div class="o_assignation_leads_count"> <field name="maximum_user_leads" invisible="1"/> <field name="leads_count" widget="gauge" options="{'max_field': 'maximum_user_leads'}"/> </div> 语句没有显示任何内容。

3 个答案:

答案 0 :(得分: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 :(得分:1)

您的问题不是案例陈述,而是您以错误的方式使用变量分配

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

您将grep分配给变量x以运行-o [aA] abc.txt,因为var=something command仅为运行command分配变量。

这当然没有意义,但你很高兴你没有尝试删除文件的x=something rm *

正确的语法是

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

表示在子shell中执行grep|wc并将结果赋给变量x。我添加了引号,因为当你的命令没有返回任何内容时你会遇到没有引号的问题,因为x=是语法错误而x=""完全正常。

在bash中你有很好的语法(可以嵌套)

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

也是如此。但请务必使用#!/bin/bash开始您的脚本,因为/bin/sh通常是另一个shell而不是bash,其语法可能不起作用。

$()应该适用于每个fully POSIX compatible shell,但/bin/sh可能不完全兼容,因此使用特定的shell无论如何都是个好主意。

答案 2 :(得分: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语句,也不需要单独的echo来输出计数。 如果您确定需要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"

顺便说一句,我非常希望您使用-owc -l来计算出现次数而不是匹配行。我几乎在-c中建议grep消除额外的命令,直到我再看一遍。尼斯。 :)