用于计算文件中字符串出现次数的 Bash 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18832297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash script to count the number of occurances of a string in a file
提问by case
I have this function in my Bash script
我的 Bash 脚本中有这个功能
if [ $numberOne -gt 10 ]
then
echo "$numberOne has occurred over 10 times"
echo "email me numberOne"
elif [ $numberTwo -gt 4 ]
then echo "$numberTwo has occurred over 4 times"
echo "email me numberTwo"
elif [ $numberThree -gt 4 ]
then echo "$numberThree has occurred over 4 times"
echo "email me numberThree"
elif [ $numberFour -gt 5 ]
then echo "$numberFour has occurred over 5 times"
echo "email me numberFour"
else echo "nothing found yet"
exit
fi
}
Info: I am port checking. I run a script every minute. When a port is found to be used I write it to a file and then read the file. The number of times it's found equates to minutes. 4 times is 4 minutes, I want to know if the port is active more that a number of minutes.
信息:我正在检查端口。我每分钟运行一个脚本。当发现使用端口时,我将其写入文件,然后读取该文件。找到它的次数等于分钟。4 次是 4 分钟,我想知道端口是否处于活动状态超过分钟数。
What I want to do:
我想做的事:
3 numbers will populate a file. At some point one of them will be present more than 4 times and then the rest will also appear. At that point I want an alert when the first of them occurs or [all of them after the first occurrence]. Ideally the alert will be like this: "NumberOne has been open for 4 minutes". And after 1 minute it will be "5 minutes"-until I stop it or a threshold is reached, I don't know yet.
3 个数字将填充一个文件。在某些时候,其中一个将出现 4 次以上,然后其余的也将出现。那时我想要一个警报,当它们中的第一个发生或 [第一次发生后的所有]。理想情况下,警报应该是这样的:“NumberOne 已打开 4 分钟”。1 分钟后将是“5 分钟”——直到我停止它或达到阈值,我还不知道。
The problem: The problem here is that when NumberOne occurs more than 10 times AND NumberTwo occurs 4 times after that it only echoes NumberTwo.
问题:这里的问题是,当 NumberOne 出现 10 次以上且 NumberTwo 出现 4 次后,它只回显 NumberTwo。
I thought I could use continue
after each then
, but I can't!
我以为我可以continue
在 each 之后使用then
,但我不能!
Also: my NumberOne variable. NumberOne=$(grep -wc "port=51555" monitor.txt)
另外:我的 NumberOne 变量。 NumberOne=$(grep -wc "port=51555" monitor.txt)
回答by konsolebox
To get the number of occurrences a string has on a file, use grep -c
:
要获取字符串在文件中出现的次数,请使用grep -c
:
grep -c something file
An example application to this is:
对此的一个示例应用是:
file="/path/to/file"
numberOne_string="something"
numberOne=$(grep -c "$numberOne_string" "$file")
And about your logic the best option I think could only be:
关于你的逻辑,我认为最好的选择只能是:
if [[ numberOne -gt 10 || numberTwo -gt 4 || numberThree -gt 4 || numberFour -gt 5 ]]; then
if [[ numberOne -gt 10 ]]; then
echo "$numberOne has occurred over 10 times"
echo "email me numberOne"
fi
if [[ numberTwo -gt 4 ]]; then
echo "$numberTwo has occurred over 4 times"
echo "email me numberTwo"
fi
if [[ numberThree -gt 4 ]]; then
echo "$numberThree has occurred over 4 times"
echo "email me numberThree"
fi
if [[ numberFour -gt 5 ]]; then
echo "$numberFour has occurred over 5 times"
echo "email me numberFour"
fi
else
echo "nothing found yet"
fi
Or a negated version of it.
或者它的否定版本。
Another requires a variable:
另一个需要一个变量:
nothing_found=true
if [[ numberOne -gt 10 ]]; then
echo "$numberOne has occurred over 10 times"
echo "email me numberOne"
nothing_found=false
fi
if [[ numberTwo -gt 4 ]]; then
echo "$numberTwo has occurred over 4 times"
echo "email me numberTwo"
nothing_found=false
fi
if [[ numberThree -gt 4 ]]; then
echo "$numberThree has occurred over 4 times"
echo "email me numberThree"
nothing_found=false
fi
if [[ numberFour -gt 5 ]]; then
echo "$numberFour has occurred over 5 times"
echo "email me numberFour"
nothing_found=false
fi
if [[ $nothing_found == true ]]; then
echo "nothing found yet"
fi
回答by deivid
You are checking different variables... you don't need elif
there... Change it with independent if
's. For example:
您正在检查不同的变量......你不需要elif
那里......用独立if
的改变它。例如:
if [ $numberOne -gt 10 ]
then
echo "$numberOne has occurred over 10 times"
echo "email me numberOne"
fi
if [ $numberTwo -gt 4 ]
then
echo "$numberTwo has occurred over 4 times"
echo "email me numberTwo"
if
if [ $numberThree -gt 4 ]
then
echo "$numberThree has occurred over 4 times"
echo "email me numberThree"
fi
if [ $numberThree -gt 5 ]
then
echo "$numberFour has occurred over 5 times"
echo "email me numberFour"
fi
if [ $numberOne -le 10 -a $numberTwo -le 4 -a $numberThree -le 4 -a $numberFour -le 5 ]
then
echo "nothing found yet"
exit
fi
回答by tripleee
Here is a refactoring which reduces code duplication.
这是减少代码重复的重构。
found=false
while read variable count; do
value=${!$variable}
if [ "$value" -gt "$count" ]; then
echo "$value occurred more than $count times"
echo "email me $variable"
found=true
fi
done <<____HERE
numberOne 10
numberTwo 4
numberThree 4
numberFour 5
____HERE
if ! $found; then
echo "Nothing found yet"
fi
If you don't have Bash, you can use eval value="\$$variable"
instead.
如果你没有 Bash,你可以用它eval value="\$$variable"
代替。
If you want to populate the variables on the fly, you could do the grep -c
inside the loop, and put e.g. a regex, or just the port number, in the first column of the here document instead.
如果您想即时填充变量,您可以grep -c
在循环内部进行,并在此处文档的第一列中放置例如正则表达式或仅端口号。