按换行符拆分 bash 字符串

我找到 这个了。

我正在尝试:

x='some
thing'


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

我没有运气,我以为它可以工作,双反斜杠:

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

但事实并非如此。

为了测试我没有得到我想要的,我正在做:

echo ${y[1]}

获得:

some
thing

我想成为:

some

我希望 y是一个数组 [some, thing]。我如何做到这一点?

168234 次浏览

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