Split Bash String by Newline Characters

I found this.

And I am trying this:

x='some
   thing'

y=(${x//\n/})

And I had no luck, I thought it could work with double backslash:

y=(${x//\\n/})

But it did not.

To test I am not getting what I want I am doing:

echo ${y[1]}

Getting:

some
thing

Which I want to be:

some

I want y to be an array [some, thing]. How can I do this?

2

2 Answers

Another way:

x=$'Some\nstring'
readarray -t y <<<"$x"

Or, if you don't have bash 4, the bash 3.2 equivalent:

IFS=$'\n' read -rd '' -a y <<<"$x"

You can also do it the way you were initially trying to use:

y=(${x//$'\n'/ })

This, however, will not function correctly if your string already contains spaces, such as 'line 1\nline 2'. To make it work, you need to restrict the word separator before parsing it:

IFS=$'\n' y=(${x//$'\n'/ })

...and then, since you are changing the separator, you don't need to convert the \n to space anymore, so you can simplify it to:

IFS=$'\n' y=($x)

This approach will function unless $x contains a matching globbing pattern (such as "*") - in which case it will be replaced by the matched file name(s). The read/readarray methods require newer bash versions, but work in all cases.

10

There is another way if all you want is the text up to the first line feed:

x='some
thing'

y=${x%$'\n'*}

After that y will contain some and nothing else (no line feed).

What is happening here?

We perform a parameter expansion substring removal (${PARAMETER%PATTERN}) for the shortest match up to the first ANSI C line feed ($'\n') and drop everything that follows (*).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest