i would like to search a variable for a pattern, without having make any calls to external tools.
i have a code like this:
COUNTPRO2="gine is very bad
vine is pretty good"
case "${COUNTPRO2}" in
*vine*)
factor=${COUNTPRO2}
echo $factor
;;
esac
If the variable contains a specific pattern, i.e. in this case "vine", then i want the case statement to output ONLY the line containing the pattern..i.e.
vine is pretty good
is this possible?
what i was doing before was:
factor=$(echo "${COUNTPRO2}" | egrep vine)
I would like to avoid calling the egrep.
the solution needs to be portable as i intend to use it on linux, aix and sunos
It would probably be useful if you were to tell us which items the different platforms had in common: bash, ksh, zsh, awk, perl, grep , etc.
Here's a solution using an array, loop, and case:
#!/usr/bin/env bash
# @(#) s1 Demonstrate shell array with case selector.
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
db() { : ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
C=$HOME/bin/context && [ -f $C ] && $C
v1="gine is very bad
vine is pretty good"
pl " Input data variable, piped into cat:"
echo "$v1" | cat -n
pl " Input data array with printf:"
declare -a a1="$v1"
printf "%s\n" "${a1[*]}"
pl " Looking through each element in the array:"
IFS=$'\n'
for line in ${a1[*]}
do
db " Working on line [$line]"
case $line in
(*vine*) echo " HIT! Found vine." ;;
esac
done
exit 0
producing:
$ ./s1
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.4 (jessie)
bash GNU bash 4.3.30
-----
Input data variable, piped into cat:
1 gine is very bad
2 vine is pretty good
-----
Input data array with printf:
gine is very bad
vine is pretty good
-----
Looking through each element in the array:
db, Working on line [gine is very bad]
db, Working on line [vine is pretty good]
HIT! Found vine.
#!/bin/ksh
COUNTPRO2="gine is very bad
vine is pretty good"
while IFS= read -r factor
do case "$factor" in
(*vine*)printf '%s\n' "$factor"
;;
esac
done <<EOF
$COUNTPRO2
EOF
Note that I used printf instead of echo because the output you get from echo might not be what you want if a line in the expansion of $COUNTPRO2 starts with a hyphen or contains any backslash characters. And, using a here-document instead of an array makes it portable to many more shells.
Forking and execing an external utility is a VERY slow operation when compared to the actions required to perform a case statement pattern match.
Although the above was written and tested using a Korn shell, this should work with any shell that is based on Bourne shell syntax (including a 1970's vintage pure Bourne shell).
Old Bourne shells do not like ( ) in a case selector, and no -r for read.
#!/bin/sh
COUNTPRO2="gine is very bad
vine is pretty good"
while IFS= read factor
do
case "$factor" in
*vine*)
printf '%s\n' "$factor"
;;
esac
done <<EOF
$COUNTPRO2
EOF
A here-document uses a /tmp file. Another method is a pipe to the while loop
#!/bin/sh
COUNTPRO2="gine is very bad
vine is pretty good"
printf '%s\n' "$COUNTPRO2" |
while IFS= read factor
do
case "$factor" in
*vine*)
printf '%s\n' "$factor"
;;
esac
done