我想创建一个接受元音的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>
语句没有显示任何内容。
答案 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"
顺便说一句,我非常希望您使用-o
和wc -l
来计算出现次数而不是匹配行。我几乎在-c
中建议grep
消除额外的命令,直到我再看一遍。尼斯。 :)