1

I'm trying to parse args like I do in C:

if (str[i] == something && str[i + 1] == something) {
      //do somthing
}

I can't figure out how to do the str[i + 1]. Here's what I tried:

for a in $@ ; do
        if [ $a == "create" ] && [sed 's/table/']; then
            echo "create database"
        fi
done

I'm trying to to something if I find create and right after create if there's database.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Tsirsuna
  • 130
  • 2
  • 16
  • See [BASH scripting: n-th parameter of $@ when the index is a variable?](https://stackoverflow.com/q/10749976/4154375), [How to get the nth positional argument in bash?](https://stackoverflow.com/q/1497811/4154375), and [Accessing shell script arguments by index](https://stackoverflow.com/q/16916281/4154375). – pjh Jan 12 '22 at 12:58

3 Answers3

3

You can do this in a loop with a flag, but the usual way to do this sort of thing is to shift arguments as you consume them. Something like:

#!/bin/sh

while test $# -gt 0; do
    case $1 in
    create) shift; echo "arg after create is '$1'";;
    # ...
    esac
    shift
done
William Pursell
  • 204,365
  • 48
  • 270
  • 300
3

In bash, we can use indirect variables to do the same thing:

for ((i = 1, j = 2; i < $#; i++, j++)); do
    if [[ ${!i} == "create" && ${!j} == "database" ]]; then
        echo "create database"
        break
    fi
done

This technique does not consume the arguments like shift does.

Ref: 4th paragraph of 3.5.3 Shell Parameter Expansion


A couple of points about your code:

for a in $@ ; do
        if [ $a == "create" ] && [sed 's/table/']; then
            echo "create database"
        fi
done
  1. Always quote "$@" -- that's the only way to keep "arguments with whitespace" together.
  2. in bash, use [[...]] instead of [...] -- the double bracket form is more safe regarding unquoted variables.
  3. the brackets are not mere syntax, [ is a command. For external commands, don't use brackets:
    if [[ $a == "create" ]] && sed 's/table/other/' some_file; then
    
    Carefully read help if at a bash prompt.
pjh
  • 6,388
  • 2
  • 16
  • 17
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0

You may call it cheating, but you could put $@ into an array str initially:

str=( "$@" )
i=... # Whatever you need
if [[ ${str[$i]} == something && ${str[$((i+1))]} == something ]]
then
  ....

This comes closest. However, in practice it is often more convenient to reconsider your algorithm, rather than to bend a language to make it look similar to a language you are already familiar with.

user1934428
  • 19,864
  • 7
  • 42
  • 87