1

Suppose I have a string with pipe separator:

str="1|2|3|4"

I want them to be assigned to specific variables.

var_a=1
var_b=2
var_c=3
var_d=4

I am doing it in this way:

var_a="`echo $str | cut -d'|' -f1`"
var_b="`echo $str | cut -d'|' -f2`"
var_c="`echo $str | cut -d'|' -f3`"
var_d="`echo $str | cut -d'|' -f4`"

Can this be done in an efficient way? Please suggest.

2
  • Would it be ok to use an array instead of five different variables?
    – Socowi
    Commented Jul 10, 2018 at 14:18
  • BTW, echo $str is itself buggy; echo "$str" is slightly better (won't replace a * with a list of filenames, for example); printf '%s\n' "$str" is much better (works correctly with all possible values, including -n or -e, which some versions of echo will consume). See BashPitfalls #14, and the APPLICATION USAGE section of the POSIX echo specification. Commented Jul 10, 2018 at 14:29

2 Answers 2

4

It is better to use an array to store individual delimited values:

str="1|2|3|4"
IFS='|' read -ra arr <<< "$str"

#examine array values
declare -p arr

declare -a arr='([0]="1" [1]="2" [2]="3" [3]="4")' 

To loop through array, use:

for i in "${arr[@]}"; do echo "$i"; done

1
2
3
4
3
  • That's fair assuming the OP really wants to read a completely variable number of items. I'm not sure we know that's the case, vs four specific fields having distinct meanings. Commented Jul 10, 2018 at 14:23
  • Yes, I just suggested an alternative assuming variable number of delimited values in input.
    – anubhava
    Commented Jul 10, 2018 at 14:25
  • 1
    Thanks. I'll use array for this purpose. Commented Jul 10, 2018 at 14:36
3
IFS='|' read -r var_a var_b var_c var_d rest <<<"$str"

rest is the variable that gets further columns after the first four, should any others exist. If you just want to discard them, the conventional name to use for a placeholder variable is _.

This is covered in detail in BashFAQ #1: How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?

1
  • Awesome one-liner Commented Jul 10, 2018 at 14:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.