0

I have a issue in processing data of below variable to the dynamic array

variable_1='A|B|C|D' -> dynamic_array=(A B C D)

I tried using sed command to replace '|' with space and how do I pass data to dynamic_array

Is their any way to achieve within one line of code?

AdminBee
  • 22,803

3 Answers3

4

Without changing IFS, since Bash 4.4:

readarray -td '|' arr < <(printf '%s' "$var")
$ var='A|B|C|D'
$ readarray -td '|' arr < <(printf '%s' "$var")
$ echo "${arr[0]}"; echo "${arr[3]}"
A
D

See help readarray for explanation.

Note: My previous suggestion (readarray -td '|' arr <<< "$var"), although briefer, would insert a spurious newline at the last array element, as Freddy pointed.

Quasímodo
  • 18,865
  • 4
  • 36
  • 73
3

Assuming bash:


You can make use of word splitting. Internal Field Separator (IFS) defaults to space, tab or newline. But you can override it with setting the IFS environment variable, then you can use the normal ways to create a variable:

set -f # disable filename expansion
IFS='|' arr=($variable_1)

or declare:

IFS='|' declare -a 'arr=($variable_1)'

or read:

IFS='|' read -ra arr  <<<  "$variable_1"

If you change the IFS variable like this, you may want to save it first in another variable and reset it afterwards:

OLD_IFS="$IFS"
# my commands
IFS="$OLD_IFS"
pLumo
  • 22,565
  • can you explain a little bit – codeholic24 Nov 11 '20 at 10:48
  • 3
    You should mention that after the first, IFS will stay set to |, potentially breaking other commands. IFS='|' arr=($var) does NOT work like IFS= read .. -- IFS does not revert to its old value after that. –  Nov 11 '20 at 11:53
  • read -ra is the best answer, but I would strongly encourage you to be more vigilant about quoting your variables. The first one in particular is not recommended unless you also do set -f – glenn jackman Nov 11 '20 at 14:29
  • thanks, updated my answer to reflect your comments. Very much appreciated. – pLumo Nov 12 '20 at 06:56
  • @glennjackman, read -ra only works for data that doesn't contain newline characters. It also removes trailing empty elements. For that you need: set -o noglob; IFS='|'; array=($string"") – Stéphane Chazelas Nov 12 '20 at 09:44
  • @plumo note that when you do var=value command then the var is only set for the duration of the command. I'd pull out a reference from the manual but I'm on my phone – glenn jackman Nov 12 '20 at 12:49
0

Assuming zsh, you can use the s parameter expansion flag which will work whatever characters or non-characters the elements contain:

$ string=$'first element|second\nbinary\x80element\0||second-last|'
$ array=("${(@s[|])string}")
$ typeset -p string array
typeset string=$'first element|second\nbinary\M-\C-@element\C-@||second-last|'
typeset -a array=( 'first element' $'second\nbinary\M-\C-@element\C-@' '' second-last '' )

Note that the empty string is split into one empty element (string='' gives array=( '' ), not array=( )).