James Lam
James Lam

Reputation: 1269

Chaining Bash Statements

I've been struggling with this for some time but my current bash statements look like:

trim() {
    local var="$*"
    var="${var#"${var%%[![:space:]]*}"}"   # remove leading whitespace characters
    var="${var%"${var##*[![:space:]]}"}"   # remove trailing whitespace characters
    echo -n "$var"
}

with

CV=trim `$(cat somejson | grep '\"fdsaf\"' | sed 's/  "fasdf": "\(.*\)",/\1/')`

This fails because I believe

$(cat somejson | grep '\"fdsaf\"' | sed 's/ "fasdf": "\(.*\)",/\1/')

gets interpreted as a bash command and an error is thrown.

Instead, I refactored this into

CV=$(cat somejson | grep '\"dasf\"' | sed 's/  "fasd": "\(.*\)",/\1/')
NEW_CV=$(trim $UNTRIMMED_PROD_NAME)

Is there a cleaner way to chain these two commands together? My refactored approach looks messy.

Upvotes: 0

Views: 54

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80931

Assuming CV and UNTRIMMED_PROD_NAME are the same variable (typo) then yes, just nest the $() bits.

NEW_CV=$(trim $(grep '\"dasf\"' somejson | sed 's/  "fasd": "\(.*\)",/\1/'))

Your original CV=trim `....` was not working correctly because you forgot the outer $() and the shell saw that as:

Set CV=trim in the environment of the command to be run from the results of running the output of the cat somejson | grep '\"fdsaf\"' | sed 's/ "fasdf": "\(.*\)",/\1/' command (yes running the output of, you have two executions there).

CV=trim `$(cat somejson | grep '\"fdsaf\"' | sed 's/  "fasdf": "\(.*\)",/\1/')`

first expands the inner command $() and gets a result and ends up with

CV=trim `cat-grep-sed-result`

then expands the backtick command execution (the cat-grep-sed-result string taken as a command) which is probably throwing an error and resulting in an empty string and ending up with

CV=trim

which is then processed as an assignment.

Upvotes: 3

Related Questions