Search code examples
linuxbashvariablescut

Pull values in a variable from another variable


I am trying to pull a value from a sequence, based on the entry of the parameter in the file. In my case, the values are going to be either "seq", "date", or "count".

function ParseHeader {
    local varHeaderLine=$1
    local varType=$2
    local varOut=""
    
    if [[ -z "$varType" ]]; then
        echo "Cannot find! - ($varType)"
        exit 1
        
    elif [[ "$varType" = "seq" ]]; then
        varOut=$(echo "$varHeaderLine" | cut -d\| -f 3)
        echo "Sequence: $varOut"
    elif [[ "$varType" = "date" ]]; then
        varOut=$(echo "$varHeaderLine" | cut -d\| -f 4)
        echo "Date: $varOut"
    elif [[ "$varType" = "count" ]]; then
        varOut=$(echo "$varHeaderLine" | cut -d\| -f 5)
        echo "Line Count: $varOut"
    else
        echo "Invalid input! Your Header is: $varHeaderLine"
    fi
        return $?
}

sequence='XXXXX|Y|1|20220429|9999'

ProfSeq=$(ParseHeader "${sequence}" "count")


echo $ProfSeq

This is a piece out of the whole file, but what is happening here is that I am going to receive a file, pull its sequence, and then pull some value from that particular sequence. Thanks for the help, this is what I ended up with. Now I'm looking for it to be less CPU intensive, if possible.

Note: This piece is out of a while file script that will be running daily for different servers in different environments


Solution

  • Focusing solely on the current piece of code ...

    Assumptions/Understandings:

    • the variable ProfSeq is to contain the output from the function's echo calls; we can eliminate the subprocess call (ProfSeq=$( ... subprocess call ...)) by having the function replace the echo "..." calls with ProfSeq="..." (ie, have the function directly populate the ProfSeq variable
    • additional performance improvements can be derived from eliminating the double subprocess calls to split varHeaderLine ($(echo ... | cut ...)) with the bash/read builtin

    One idea for a function rewrite:

    ParseCOTHeader () {
    
    local varHeaderLine=$1
    local -l varType=$2                                # force to all lowercase
    local ignore1 ignore2 in_seq in_date in_count rc
    
    # split varHeaderLine into 5 variables based on '|' delimiter:
    # NOTE: assumes varHeaderLine has exactly 5x '|' delimited fields otherwise OP
    #       may want to add some code to validate the structure of varHeaderLine
    
    IFS='|' read -r ignore1 ignore2 in_seq in_date in_count <<< "${varHeaderLine}"
    
    # reset variables:
    
    ProfSeq=
    rc=0
    
    if [[ -z "${varType}" ]]
    then
        ProfSeq="Cannot find! - ($2)"                  # since varType=$2 is empty at this point we will always print '()' ... ?
        rc=1
    else
        case "${varType}" in
             seq)    ProfSeq="Sequence: ${in_seq}" ;;
             date)   ProfSeq="Date: ${in_date}" ;;
             count)  ProfSeq="Line Count: ${in_count}" ;;
             *)      ProfSeq="Invalid input! Your Header is: '$varHeaderLine'"
                     rc=1 ;;
        esac
    fi
    
    return "${rc}"
    }
    

    Putting the function through its paces:

    $ sequence='SWHHR|H|1|20220429|9999'
    
    $ ParseCOTHeader "${sequence}" 'seq'
    $ echo "$? : ${ProfSeq}"
    0 : Sequence: 1
    
    $ ParseCOTHeader "${sequence}" 'DaTe'
    $ echo "$? : ${ProfSeq}"
    0 : Date: 20220429
    
    $ ParseCOTHeader "${sequence}" 'COUNT'
    $ echo "$? : ${ProfSeq}"
    0 : Line Count: 9999
    
    $ ParseCOTHeader "${sequence}" 'fire-truck'
    $ echo "$? : ${ProfSeq}"
    1 : Invalid input! Your Header is: 'SWHHR|H|1|20220429|9999'
    
    $ ParseCOTHeader "${sequence}" ''
    $ echo "$? : ${ProfSeq}"
    1 : Cannot find! - ()
    

    If repeated calls to the function need to save the message string in different variables:

    • add the line local -n myoutput=$3 in the top section of the function (this defines a local nameref variable myoutput to act as a pointer to the variable name passed in $3)
    • replace all ProfSeq="..." with myoutput="..." in the function
    • remove the line ProfSeq= (variable reset) in the function

    Taking the new function for a test spin:

    $ sequence='SWHHR|H|1|20220429|9999'
    
    $ ParseCOTHeader "${sequence}" 'seq' ProfSeq
    $ echo "$? : ${ProfSeq}"
    0 : Sequence: 1
    
    $ ParseCOTHeader "${sequence}" 'DaTe' ProfSeq
    $ echo "$? : ${ProfSeq}"
    0 : Date: 20220429
    
    $ ParseCOTHeader "${sequence}" 'COUNT' ProfSeq
    $ echo "$? : ${ProfSeq}"
    0 : Line Count: 9999
    
    $ ParseCOTHeader "${sequence}" 'fire-truck' SomeOtherVar
    $ echo "$? : ${SomeOtherVar}"
    1 : Invalid input! Your Header is: 'SWHHR|H|1|20220429|9999'
    
    $ ParseCOTHeader "${sequence}" '' YetAnotherVar
    $ echo "$? : ${YetAnotherVar}"
    1 : Cannot find! - ()