Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to do "split" in bash

22 views
Skip to first unread message

Kenny McCormack

unread,
Sep 27, 2021, 7:20:37 AM9/27/21
to
In earlier episodes of our saga, I had complained about the lack of a
"split" function in bash. By "split", I mean taking a string and making an
array out of it, as does the AWK "split" function.

I have now figured out a general solution to this problem. Observe:

$ od -bc <<< "$IFS"
0000000 040 011 012 012
\t \n \n
0000004
$ IFS=',;:' read -a foo <<< 'word 1,that and; ANother string: Foo on you!!!'
$ printf -- "---> %s\n" "${foo[@]}"
---> word 1
---> that and
---> ANother string
---> Foo on you!!!
$ od -bc <<< "$IFS"
0000000 040 011 012 012
\t \n \n
0000004
$

--
The whole aim of practical politics is to keep the populace alarmed (and hence clamorous
to be led to safety) by menacing it with an endless series of hobgoblins, all of them imaginary.

H. L. Mencken

Kenny McCormack

unread,
Sep 27, 2021, 10:45:39 AM9/27/21
to
In article <sis9e1$2konq$1...@news.xmission.com>,
Kenny McCormack <gaz...@shell.xmission.com> wrote:
>In earlier episodes of our saga, I had complained about the lack of a
>"split" function in bash. By "split", I mean taking a string and making an
>array out of it, as does the AWK "split" function.

Note that this same general idea can be used to address another question
that I've wrestled with (and posted about) previously: That is, removing
leading/trailing blanks from a string in bash. Observe:

$ foo=" leading and trailing spaces "
$ read -r bar <<< "$foo"

In fact, you could even do:

$ read -r foo <<< "$foo"

to do it "in place".

--
He must be a Muslim. He's got three wives and he doesn't drink.

Kaz Kylheku

unread,
Sep 27, 2021, 12:01:10 PM9/27/21
to
On 2021-09-27, Kenny McCormack <gaz...@shell.xmission.com> wrote:
> In earlier episodes of our saga, I had complained about the lack of a
> "split" function in bash. By "split", I mean taking a string and making an
> array out of it, as does the AWK "split" function.
>
> I have now figured out a general solution to this problem. Observe:

You were beaten to it by days by one Abhishek Prakash, who blogged about
it on September 4. It comes up as the first hit in a search for "split
string into array in bash" in ducu

https://linuxhandbook.com/bash-split-string/

Method 1: Split string using read command in Bash

...
my_string="Ubuntu;Linux Mint;Debian;Arch;Fedora"
IFS=';' read -ra my_array <<< "$my_string"

The idea does not originate with Prakash. The following 2019-dated
StackOverflow answer documents the approach also.

https://stackoverflow.com/a/58600824/1250772

Stil blows goats, but its nice not having to save, assign and
restore IFS, at least.

Kaz Kylheku

unread,
Sep 27, 2021, 12:12:18 PM9/27/21
to
On 2021-09-27, Kaz Kylheku <480-99...@kylheku.com> wrote:
> The idea does not originate with Prakash. The following 2019-dated
> StackOverflow answer documents the approach also.
>
> https://stackoverflow.com/a/58600824/1250772

Just before closing the page, I noticed that the plagiarist just cribbed
the IFS = ... read -a .. <<< trick from the massively upvoted, accepted
answer to the same question, dated 2012:

https://stackoverflow.com/a/10586169/1250772

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal

Kenny McCormack

unread,
Sep 27, 2021, 12:22:14 PM9/27/21
to
In article <202109270...@kylheku.com>,
Kaz Kylheku <480-99...@kylheku.com> wrote:
>On 2021-09-27, Kenny McCormack <gaz...@shell.xmission.com> wrote:
>> In earlier episodes of our saga, I had complained about the lack of a
>> "split" function in bash. By "split", I mean taking a string and making an
>> array out of it, as does the AWK "split" function.
>>
>> I have now figured out a general solution to this problem. Observe:
>
>You were beaten to it by days by one Abhishek Prakash, who blogged about
>it on September 4. It comes up as the first hit in a search for "split
>string into array in bash" in ducu

What makes you think I read any of those websites (Stack*, LinuxWhatever,
...) ?

--
Faith doesn't give you the answers; it just stops you from asking the questions.

Janis Papanagnou

unread,
Sep 27, 2021, 12:48:20 PM9/27/21
to
On 27.09.2021 18:22, Kenny McCormack wrote:
> In article <202109270...@kylheku.com>,
> Kaz Kylheku <480-99...@kylheku.com> wrote:
>> On 2021-09-27, Kenny McCormack <gaz...@shell.xmission.com> wrote:
>>> In earlier episodes of our saga, I had complained about the lack of a
>>> "split" function in bash. By "split", I mean taking a string and making an
>>> array out of it, as does the AWK "split" function.
>>>
>>> I have now figured out a general solution to this problem. Observe:
>>
>> You were beaten to it by days by one Abhishek Prakash, who blogged about
>> it on September 4. It comes up as the first hit in a search for "split
>> string into array in bash" in ducu
>
> What makes you think I read any of those websites (Stack*, LinuxWhatever,
> ...) ?

I suppose he supposed that you'd do some searching on "The Internet"
(as often suggested here) before asking.

But would that be necessary at all? Since you seem to have asked that
question also here in September this year. Of course you'll find in a
response of mine also the "IFS=... read..." proposal suggested (and
demonstrated in an example for ksh; the bash manual inspection for
syntax adjustments was suggested for homework).

Janis *shrug*

Lew Pitcher

unread,
Sep 27, 2021, 12:57:31 PM9/27/21
to
I suggest that even the "read" is redundant
foo=" leading and trailing spaces "
bar=( $foo }

And, of course, it works with an altered IFS
oldIFS=$IFS
IFS=e bar=$($foo)
IFS=$oldIFS


--
Lew Pitcher
"In Skills, We Trust"

Lew Pitcher

unread,
Sep 27, 2021, 12:58:04 PM9/27/21
to
On Mon, 27 Sep 2021 16:57:26 +0000, Lew Pitcher wrote:

> On Mon, 27 Sep 2021 14:45:32 +0000, Kenny McCormack wrote:
>
>> In article <sis9e1$2konq$1...@news.xmission.com>,
>> Kenny McCormack <gaz...@shell.xmission.com> wrote:
>>>In earlier episodes of our saga, I had complained about the lack of a
>>>"split" function in bash. By "split", I mean taking a string and making an
>>>array out of it, as does the AWK "split" function.
>>
>> Note that this same general idea can be used to address another question
>> that I've wrestled with (and posted about) previously: That is, removing
>> leading/trailing blanks from a string in bash. Observe:
>>
>> $ foo=" leading and trailing spaces "
>> $ read -r bar <<< "$foo"
>>
>> In fact, you could even do:
>>
>> $ read -r foo <<< "$foo"
>>
>> to do it "in place".
>
> I suggest that even the "read" is redundant
> foo=" leading and trailing spaces "
> bar=( $foo }
Typo
bar=( $foo )

Martijn Dekker

unread,
Sep 29, 2021, 1:29:36 PM9/29/21
to
Op 27-09-21 om 18:01 schreef Kaz Kylheku:
> Stil blows goats, but its nice not having to save, assign and
> restore IFS, at least.

To do this safely in shell, we have to not only set IFS to the separator
but also disable pathname expansion (globbing).

On bash 5.0 and higher, you can use 'local -' to make all shell option
changes local to a function. Making IFS local was already trivial on
older bash versions. This allows the following simple reimplementation
of awk split() on bash 5.0+:

function split
{
local -n a=$2
local IFS=$3 -
set -o noglob
a=( $1 )
}

On ksh93 and mksh, shell options are always local for functions declared
with the 'function' keyword, so the *ksh version is even simpler:

function split
{
nameref a=$2
typeset IFS=$3
set -o noglob
a=( $1 )
}


--
|| modernish -- harness the shell
|| https://github.com/modernish/modernish
||
|| KornShell lives!
|| https://github.com/ksh93/ksh
0 new messages