#!/bin/bash # Minimalist implementations of the 'index' and 'rindex' functions in pure Bash # returns a 0 based offset into your haystack string # This is provided solely as-is, and all I ask is a one line thank you note # with my email address. # Written by Robin H. Johnson function index() { local haystack="$1" local needle="$2" local fromstart="${3-0}" haystack="${haystack:${fromstart}}" local tmp="${haystack/${needle}*}" [ "${#tmp}" -ge "${#haystack}" ] && echo -1 || echo $((${#tmp}+${fromstart}-1)) } function rindex() { local haystack="$1" local needle="$2" local fromend="${3-0}" haystack="${haystack:0:$((${#haystack}-${fromend}+1))}" local tmp="${haystack%${needle}*}" [ "${#tmp}" -ge "${#haystack}" ] && echo -1 || echo $((${#tmp}-1)) } # Testing code HAYSTACK="Mary had a little lamb but the lamb had had measles" NEEDLE="had" echo "'${HAYSTACK}' (${#HAYSTACK})" echo -n "Looking for needle '${NEEDLE}' [expect 4]: " index "${HAYSTACK}" "${NEEDLE}" echo -n "Looking for needle '${NEEDLE}' after 7 [expect 35]: " index "${HAYSTACK}" "${NEEDLE}" 7 echo -n "Looking for needle 'foo' [expect -1]: " index "${HAYSTACK}" "foo" echo -n "Looking for needle 'foo' after 7 [expect -1]: " index "${HAYSTACK}" "foo" 7 echo -n "Looking for needle '${NEEDLE}' in reverse [expect 39]: " rindex "${HAYSTACK}" "${NEEDLE}" echo -n "Looking for needle '${NEEDLE}' in reverse skipping 10 [expect 35]: " rindex "${HAYSTACK}" "${NEEDLE}" 10 echo -n "Looking for needle '${NEEDLE}' in reverse skipping 20 [expect 4]: " rindex "${HAYSTACK}" "${NEEDLE}" 20 echo -n "Looking for needle 'foo' in reverse [expect -1]: " rindex "${HAYSTACK}" "foo" echo -n "Looking for needle 'foo' in reverse skipping 10 [expect -1]: " rindex "${HAYSTACK}" "foo" 10