Dynamic case statement in bash

前端 未结 5 1361
执念已碎
执念已碎 2020-12-20 01:25

I\'m trying to figure out how to create a dynamic case statement in a bash script.

For example, let\'s say I have the output of an awk statement with the following c

相关标签:
5条回答
  • 2020-12-20 01:32

    You can approach this in a couple of different hacky ways:

    pattern=($(awk_command))     # red\ngreen\nblue\n
    saveIFS=$IFS
    IFS='|'
    pattern="^(${pattern[*]})$"  # ^(red|green|blue)$  (perhaps hackish)
    IFS=$saveIFS
    
    # simple regex match if statement (not hackish)
    if [[ $var =~ $pattern ]]
    then
        do_something
    fi
    
    # or a backwards case statement (very hackish)
    case 1 in    # this could be a variable or a command substitution
        $([[ $var =~ $pattern]] && echo 1) )  # the echo 1 could be another command or the 1 could be yet another variable
            do_something;;
        * )
            do_default;;
    esac
    
    0 讨论(0)
  • 2020-12-20 01:38

    A case statement is probably not the right tool for the job. If you store the awk output in an array then you can loop through the array to find if a choice is in it, and as a bonus can figure out which index that is, too.

    #!/bin/bash
    
    # Store command output in an array so each word is a separate array item.    
    list=($(echo $'red\ngreen\nblue'))
    my_var=blue
    
    for ((i = 0; i < ${#list}; i++)); do
        if [[ ${list[$i]} = $my_var ]]; then
            echo "found at index $i"
            break
        fi
    done
    
    if ((i == ${#list})); then
        echo "not found"
    fi
    
    0 讨论(0)
  • 2020-12-20 01:45

    You can't do this with a case statement, but it's easy enough to set up your own helper to check for list membership.

    # stub to simulate this arbitrary call
    my_awk_command() { printf '%s\n' red green blue; }
    # helper to check list membership
    list_contains() {
      local tgt="$1"; shift
      while (( $# )); do
        if [[ $1 = "$tgt" ]] ; then
          return 0
        fi
        shift
      done
      return 1
    }
    
    # the below is Bash 4 functionality; see BashFAQ #1 on how to replace it
    readarray -t awk_output < <(my_awk_command)
    
    if list_contains "$my_var" "${my_awk_command[@]}"; then
      ...something...
    elif [[ "$my_var" = something_else ]] ; then
      ...something else...
    fi
    
    0 讨论(0)
  • 2020-12-20 01:52

    might you have to try, sorry if this might to be oot/didnt you guys looking for, (but i think it's help me out) here i have same issues to using wheter sh case with dynamic statement

    whereas i have running some function with dynamic listed parameter as input then if there's no function inside/available, it will return exit 1 or "requested not available"

    here we go.

    myfuncA(){
       echo this funcA
    }
    
    myfuncB(){
       echo this funcB
    }
    
    
    dynamicCase(){
       for areWe in $1; do
          my$areWe && echo "$areWe success" || echo "no function $1 available"
       done
    }
    
    anotherDyCase(){
       while IFS=read -r $areWe; do
          my$areWe && echo "$areWe success" || echo "no function $1 "
       done <<< $1
    }
    

    test ride:

    myListedDynamic="funcA\nfuncB\nfuncC"
    // funcA funcB funcC
    
    
    dynamicCase $myListedDynamic
    // success
    // success
    // no function available
    

    furthermore

    hope help

    0 讨论(0)
  • 2020-12-20 01:58

    You can create a dynamic case statement in bash by doing the following:

    1) ensure the list is PIPE (|) seperated. IE. red|green|blue

    2) wrap your case statement in an eval

    For example:

    valid="red|green|blue"
    
    eval "case \"$choice\" in
        $valid)
            echo do something good here
            ;;
        *)
            echo invalid colour
            ;;
    esac"
    

    This works for simple variable processing, I can not guarantee this will work in all cases.

    0 讨论(0)
提交回复
热议问题