6 added 99 characters in body
source | link

In 4.2 and before, when redirecting builtins like read or command, that splitting would even take the IFS for that readbuiltin (4.3 fixed that):

$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a b c d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. cat <<< $a'
a.b.c.d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. command cat <<< $a'
a b c d

In 4.2 and before, when redirecting builtins like read, that splitting would even take the IFS for that read (4.3 fixed that):

$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a b c d

In 4.2 and before, when redirecting builtins like read or command, that splitting would even take the IFS for that builtin (4.3 fixed that):

$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a b c d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. cat <<< $a'
a.b.c.d
$ bash-4.2 -c 'a=a.b.c.d; IFS=. command cat <<< $a'
a b c d
5 added 99 characters in body
source | link

In old versions of bash you had to quote variables after <<<. That was fixed in 4.4. In older versions, the variable would be split on IFS and the resulting words joined on space before being stored in the temporary file that makes up that <<< redirection.

In old versions of bash you had to quote variables after <<<. That was fixed in 4.4. In older versions, the variable would be split on IFS and joined on space.

In old versions of bash you had to quote variables after <<<. That was fixed in 4.4. In older versions, the variable would be split on IFS and the resulting words joined on space before being stored in the temporary file that makes up that <<< redirection.

4 added 79 characters in body
source | link

In old versions of bash you had to quote variables after <<<. That was fixed in 4.4. In older versions, the variable would be split on IFS and joined on space.

In 4.2 and before, when redirecting builtins like read, that splitting would even take the IFS for that read (4.3 fixed that):

$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a b c d

That one fixed in 4.3:

$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a.b.c.d

But $a is still subject to word splitting there:

$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo  "$x"'
a b c d

In 4.4:

$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo  "$x"'
a.b.c.d

For portability to older versions, quote your variable (or use zsh where that <<< comes from in the first place and that doesn't have that issue)

$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d

Note that that approach to split a string only works for strings that don't contain newline characters. Also note that a..b.c. would be split into "a", "", "b", "c" (no empty last element).

To split arbitrary strings you can use the split+glob operator instead (which would make it standard and avoid storing the content of a variable in a temp file as <<< does):

var='a.new
line..b.c.'
set -o noglob # disable glob
IFS=.
set -- $var'' # split+glob
for i do
  printf 'item: <%s>\n' "$i"
done

or:

array=($var'') # in shells with array support

The '' is to preserve a trailing empty element if any. That would also split an empty $var into one empty element.

Or use a shell with a proper splitting operator:

  • zsh:

    array=(${(s:.:)var} # removes empty elements
    array=("${(@s:.:)var}") # preserves empty elements
    
  • rc:

    array = ``(.){printf %s $var} # removes empty elements
    
  • fish

    set array (string split . -- $var) # not for multiline $var
    

In old versions of bash you had to quote variables after <<<. That was fixed in 4.4. In older versions, the variable would be split on IFS and joined on space.

In 4.2 and before, when redirecting builtins like read, that splitting would even take the IFS for that read (4.3 fixed that):

$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a b c d

That one fixed in 4.3:

$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a.b.c.d

But $a is still subject to word splitting there:

$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo  "$x"'
a b c d

In 4.4:

$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo  "$x"'
a.b.c.d

For portability to older versions, quote your variable (or use zsh where that <<< comes from in the first place and that doesn't have that issue)

$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d

Note that that approach to split a string only works for strings that don't contain newline characters. Also note that a..b.c. would be split into "a", "", "b", "c" (no empty last element).

To split arbitrary strings you can use the split+glob operator instead (which would make it standard and avoid storing the content of a variable in a temp file as <<< does):

var='a.new
line..b.c.'
set -o noglob # disable glob
IFS=.
set -- $var'' # split+glob
for i do
  printf 'item: <%s>\n' "$i"
done

or:

array=($var'') # in shells with array support

The '' is to preserve a trailing empty element if any. That would also split an empty $var into one empty element.

Or use a shell with a proper splitting operator:

  • zsh:

    array=(${(s:.:)var} # removes empty elements
    array=("${(@s:.:)var}") # preserves empty elements
    
  • rc:

    array = ``(.){printf %s $var} # removes empty elements
    

In old versions of bash you had to quote variables after <<<. That was fixed in 4.4. In older versions, the variable would be split on IFS and joined on space.

In 4.2 and before, when redirecting builtins like read, that splitting would even take the IFS for that read (4.3 fixed that):

$ bash-4.2 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a b c d

That one fixed in 4.3:

$ bash-4.3 -c 'a=a.b.c.d; IFS=. read x <<< $a; echo  "$x"'
a.b.c.d

But $a is still subject to word splitting there:

$ bash-4.3 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo  "$x"'
a b c d

In 4.4:

$ bash-4.4 -c 'a=a.b.c.d; IFS=.; read x <<< $a; echo  "$x"'
a.b.c.d

For portability to older versions, quote your variable (or use zsh where that <<< comes from in the first place and that doesn't have that issue)

$ bash-any-version -c 'a=a.b.c.d; IFS=.; read x <<< "$a"; echo "$x"'
a.b.c.d

Note that that approach to split a string only works for strings that don't contain newline characters. Also note that a..b.c. would be split into "a", "", "b", "c" (no empty last element).

To split arbitrary strings you can use the split+glob operator instead (which would make it standard and avoid storing the content of a variable in a temp file as <<< does):

var='a.new
line..b.c.'
set -o noglob # disable glob
IFS=.
set -- $var'' # split+glob
for i do
  printf 'item: <%s>\n' "$i"
done

or:

array=($var'') # in shells with array support

The '' is to preserve a trailing empty element if any. That would also split an empty $var into one empty element.

Or use a shell with a proper splitting operator:

  • zsh:

    array=(${(s:.:)var} # removes empty elements
    array=("${(@s:.:)var}") # preserves empty elements
    
  • rc:

    array = ``(.){printf %s $var} # removes empty elements
    
  • fish

    set array (string split . -- $var) # not for multiline $var
    
3 added 682 characters in body
source | link
2 added 682 characters in body
source | link
1
source | link