Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash regexp that match to character sequence

Tags:

bash

I am writing a bash script that receives <task> ID strings as a parameter and then executes the specified tasks. At the end of the execution, it must show the total execution time. The code must be flexible, and easy to add new conditions.

Usage: build.sh <task><task><task>...

The task id is a little bit tricky:

  • if it is only a character [a-z] then it represents all subtasks of the given task
  • if it is a character + a number, it represents only the specific subtask

Let me give you some examples:

  • build.sh a1a2: execute tasks of a1 and a2, but not a3
  • build.sh a: execute all tasks starts with char a (all subtasks of a)
  • build.sh a1b: run only task a1 and all subtasks of b
  • build.sh a1b3: run only task a1 and b3
  • build.sh ab: run all subtasks of a and b
  • build.sh *: run all tasks defined is the build script (all subtasks), like a + b + c

The execution order of the tasks is pre-defined, so actually b1a1 will execute a1b1.

This is my bash script:

#!/bin/bash -ue

# show help
function show_help() {
    if [ "$1" -eq 0 ]; then
        printf "..."
        exit 0
    fi
}

# does the build
function build {
    local title dir
    title="$1"
    dir="$2"
    printf "\n%b> building '%s'...%b\n" "$COLOR_YELLOW" "$title" "$COLOR_DEFAULT"
    cd "$WORKSPACE/../$dir"
    ./build.sh
    cd "$WORKSPACE"
}

# group A build
function build_group_a {
    if [[ "$1" == *a1* ]]; then build "task A.1" "base/xxx"; fi
    if [[ "$1" == *a2* ]]; then build "task A.2" "base/yyy"; fi
    if [[ "$1" =~ $(getRegexp a) ]]; then
      build "task A.1" "base/xxx"
      build "task A.2" "base/yyy"
    fi
}

# group B build
function build_group_b {
   # same with 'build_group_a' only conditions are different
}

# REGEXP THAT DOES NOT WORK PROPERLY
function getRegexp() {
    printf ".*%s[a-z].*" "$1"
}


show_help "$#"
START_TIME=$(date +%s)

# 'all' works but '*' not
if [[ "$1" == all ]]; then
    build_group_a a
    build_group_b b
else
    build_group_a "$1"
    build_group_b "$2"
fi

ELAPSED=$(($(date +%s) - START_TIME))
printf "build time: %s\n" "$(date -d@$ELAPSED -u +%H\ hour\ %M\ day\ %S\ sec)"

Everything works fine, tasks are executed properly in order but if I use build.sh a then nothing is executed. If I use build.sh ab, only tasks a are executed. I do not know why. It seems that the last task-ID is not processed by my regexp.

Another issue is that if I say build.sh aa1 then all tasks for a are executed but task a1 twice. Task a1 must only be executed once when a is called.

That could be great if you can guide me on how to fix the problem in my regular expression.

like image 581
zappee Avatar asked Dec 05 '25 20:12

zappee


1 Answers

On the regex part, you can try this :

#!/usr/bin/env bash

input="$1"
pattern='(\*|[[:alpha:]][[:digit:]]?)'
while [[ $input =~ $pattern ]]; do
    echo "Argument passed : ${BASH_REMATCH[1]}"
    input="${input:${#BASH_REMATCH[0]}}" # next iteration
done

test with :

bash build.sh a1b
bash build.sh "*"
like image 162
Philippe Avatar answered Dec 08 '25 12:12

Philippe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!