Let’s say I have a variable
line="This is where we select from a table."
now I want to grep how many times does select occur in the sentence.
grep -ci "select" $line
I tried that, but it did not work. I also tried
grep -ci "select" "$line"
It still doesn’t work. I get the following error.
grep: This is where we select from a table.: No such file or directory
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Have grep read on its standard input. There you go, using a pipe…
$ echo "$line" | grep select
… or a here string…
$ grep select <<< "$line"
Also, you might want to replace spaces by newlines before grepping :
$ echo "$line" | tr ' ' 'n' | grep select
… or you could ask grep to print the match only:
$ echo "$line" | grep -o select
This will allow you to get rid of the rest of the line when there’s a match.
Edit: Oops, read a little too fast, thanks Marco. In order to count the occurences, just pipe any of these to wc(1) 😉
Another edit made after lzkata‘s comment, quoting $line when using echo.
Method 2
test=$line i=0
while case "$test" in (*select*)
test=${test#*select};;(*) ! :;;
esac; do i=$(($i+1)); done
You don’t need to call grep for such a simple thing.
Or as a function:
occur() while case "$1" in (*"$2"*) set --
"${1#*"$2"}" "$2" "${3:-0}" "$((${4:-0}+1))";;
(*) return "$((${4:-0}<${3:-1}))";;esac
do : "${_occur:+$((_occur=$4))}";done
It takes 2 or 3 args. Providing any more than that will skew its results. You can use it like:
_occur=0; occur ... . 2 && echo "count: $_occur"
…which prints the occurrence count of . in ... if it occurs at least 2 times. Like this:
count: 3
If $_occur is either empty or unset when it is invoked then it will affect no shell variables at all and return 1 if "$2" occurs in "$1" fewer than "$3" times. Or, if called with only two args, it will return 1 only if "$2" is not in "$1". Else it returns 0.
And so, in its simplest form, you can do:
occur '' . && echo yay || echo shite
…which prints…
shite
…but…
occur . . && echo yay || echo shite
…will print…
yay
You might also write it a little differently and omit the quotes around $2 in both the (*"$2"*) and "${1#*"$2"}" statement. If you do that then you can use shell globs for matches like sh[io]te for the match test.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0