简体   繁体   中英

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?

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.

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 ( * ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM