Curtis Chong
Curtis Chong

Reputation: 811

Cannot Set Variable in Bash

I'm trying to set a variable in bash:

b=$(p | cut -d',' -f4)
echo $b

However, I keep ending up with:

p: command not found

I've tried every combination of brackets, curly brackets, and dollar signs but still can't get b to equal $p | cut -d',' -f4. To my understanding, the dollar signs will extract the value from the variable and the brackets are for expression containment. Is there fundamental bash syntax that I'm not aware of?

Upvotes: 1

Views: 462

Answers (4)

Fred
Fred

Reputation: 7005

The code below would also work, and would probably be higher performance by avoiding a call to the external program cut and using only the read builtin :

IFS="," read -r dummy dummy dummy b dummy  <<<"$p"
echo "$b"

You could also collect all values in an array, and reference them afterwards

IFS="," read -r -a array <<<"$p"
echo "${array[4]}"              # Print 4th field
echo "${#array[@]}"             # Print field count

In all cases, IFS="," is how you tell read to use commas as field separators, and -r forces backslashes to be used as is, not interpreted (e.g. \n will not be seen as a newline, but rather just as a literal two-character string).

Please note that the examples above only handle strings that do not contain newlines.

Upvotes: 1

gniourf_gniourf
gniourf_gniourf

Reputation: 46883

How about using Bash patterns for this?

  • With parameter expansions (super portable):

    b=${p#*,*,*,}
    b=${b%%,*}
    
  • By splitting the comma-separated string and reading only the fourth field (Bash only):

    IFS=, read -r -d '' _ _ _ b _ < <(printf '%s,\0' "$p")
    
  • By using a regex (that will also provide some sort of validation, Bash only):

    if [[ $p =~ ^[^,]*,[^,]*,[^,]*,([^,]*).*$ ]]; then
        b=${BASH_REMATCH[1]}
    else
        echo >&2 "String doesn't match"
    fi
    
  • By fully splitting the string into an array (same as point 2 above, Bash only):

    IFS=, read -r -d '' -a pary < <(printf '%s,\0' "$p")
    b=${pary[3]}
    

Upvotes: 1

swdev
swdev

Reputation: 3071

If p is a variable then try this:

b=$(echo "$p" | cut -d',' -f4)
echo $b

Upvotes: 0

Inian
Inian

Reputation: 85845

Use a here-string to expand the variable value to p to cut instead of using a pipe-line(|) which forks a new sub-shell (avoiding a new process overhead). The <<< is bash specific and not available in the POSIX shell sh.

b=$(cut -d',' -f4 <<<"$p")
echo "$b"

Also double-quote your variables to avoid word-splitting by shell.

Upvotes: 0

Related Questions