1

How to perform some steps if the 9th character of a line "$q" is an A, B, C, D, or E. Something like?

if [ ${q:9} == [A,B,C,D,E]; then

(If the 9th character is a capital A, B, C, D, or E, than do; )

I've used if [ ${q:9} == A ]; to match one letter, and was trying to construct something like the above or: if [[ "${p:9}" == "A" && "$p" == "B" && "$p" == "C" "$p" == "D" "$p" == "E"]]; then to match multiple letters, but does not seem to work regardless of the operator I use.

Matt
  • 49
  • 1
  • 10

4 Answers4

2

use a case statement:

case ${q:9} in

     [A-E])
     echo found
     ;;

esac
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
2

Just check the value of the 9th character with a regex:

[[ "${var:8:1}" =~ (A|B|C|D|E) ]]

For example:

$ v=12345678Axx
$ [[ "${v:8:1}" =~ (A|B|C|D) ]] && echo "yes" || echo "no"
yes
$ v=1234567890
$ [[ "${v:8:1}" =~ (A|B|C|D) ]] && echo "yes" || echo "no"
no

To get the 9th character note I use Bash Reference Manual → 3.5.3 Shell Parameter Expansion, so the 9th character is ${var:8:1} because the indexes are 0-based (the first one is the 0th):

${parameter:offset:length}

This is referred to as Substring Expansion. It expands to up to length characters of the value of parameter starting at the character specified by offset. If parameter is ‘@’, an indexed array subscripted by ‘@’ or ‘*’, or an associative array name, the results differ as described below. If length is omitted, it expands to the substring of the value of parameter starting at the character specified by offset and extending to the end of the value. length and offset are arithmetic expressions (see Shell Arithmetic).

If offset evaluates to a number less than zero, the value is used as an offset in characters from the end of the value of parameter. If length evaluates to a number less than zero, it is interpreted as an offset in characters from the end of the value of parameter rather than a number of characters, and the expansion is the characters between offset and that result. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the ‘:-’ expansion.

Community
  • 1
  • 1
fedorqui
  • 275,237
  • 103
  • 548
  • 598
2

Using regular expressions, you have the option of matching a single character, or a string with an arbitrary 8-character prefix:

if [[ ${q:8:1} =~ [ABCDE] ]]; then

if [[ $q =~ ^.{8}[ABCDE] ]]; then

You can also use pattern matching, although in this case it looks exactly like a regular expression:

if [[ ${q:8:1} == [ABCDE] ]]; then
chepner
  • 497,756
  • 71
  • 530
  • 681
1

Try that:

if [[ ${q:9:1} =~ [ABCDE] ]]; then

${q:9} returns all characters from the 9th on (beware, counting starts with 0). ${q:9:1} returns only one character from the 9th on. The =~ operator is a "match regex" operator.

Georg P.
  • 2,785
  • 2
  • 27
  • 53