Because i am a closet-show-off (and because the almighy Korn shell is really the only tool one ever needs ;-)) ) here is a solution in pure ksh , call it like ./script "string" "pattern" :
#! /bin/ksh
typeset chStr="$1"
typeset chPattern="$2"
typeset -i iStrIdx=1
typeset -i iPatLen=${#chPattern}
typeset -i iStrLen=$(( ${#chStr} - iPatLen + 1 ))
while [ $iStrIdx -le $iStrLen ] ; do
if [ "${chStr#${chPattern}}" != "${chStr}" ] ; then
print - "$chPattern found at position $iStrIdx"
exit 0
fi
(( iStrIdx += 1 ))
chStr="${chStr#?}"
done
print - "Pattern $chPattern not found in String"
exit 1
This script is supposed to be called with the string and the pattern on the command line. With the following slight modification it will work inside a pipeline instead, called like cat file | ./script "pattern" ( cat file represents any datastream here):
#! /bin/ksh
typeset chPattern="$1"
typeset -i iStrIdx=1
typeset -i iPatLen=${#chPattern}
typeset -i iStrLen=0
typeset -i iLineCnt=0
typeset -i lFound=0
while read chStr ; do
iStrIdx=1
iStrlen=$(( ${#chStr} - iPatLen + 1 ))
(( iLineCnt += 1 ))
(( lFound = 0 ))
while [ $iStrIdx -le $iStrLen ] ; do
if [ "${chStr#${chPattern}}" != "${chStr}" ] ; then
print - "$chPattern found at position $iStrIdx in line $iLineCnt"
(( iStrIdx = iStrLen )) # skip rest of string
(( lFound = 1 ))
else
(( iStrIdx += 1 ))
chStr="${chStr#?}"
fi
done
if ! (( lFound )) ; then
print - "$chPattern not found in line $iLineCnt"
fi
done
exit 0
To make the pattern equally dynamic as the input (i.e. the patterns to be read from a stream either) is left as an exercise to the reader.