web-dev-qa-db-fra.com

Fractionner la chaîne bash par des caractères de nouvelle ligne

J'ai trouvé ceci .

Et j'essaye ceci:

x='some
   thing'

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

Et je n’ai pas eu de chance, je pensais que cela pourrait fonctionner avec une double barre oblique inversée:

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

Mais ça n'a pas été le cas.

Pour tester je n'obtiens pas ce que je veux, je le fais:

echo ${y[1]}

Obtenir:

some
thing

Ce que je veux être:

some

Je veux que y soit un tableau [some, thing]. Comment puis-je faire ceci?

49
juanpastas

Autrement:

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

Ou, si vous n'avez pas bash 4, l'équivalent de bash 3.2:

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

Vous pouvez également le faire comme vous l'aviez initialement essayé:

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

Ceci, cependant, ne fonctionnera pas correctement si votre chaîne contient déjà des espaces, tels que 'line 1\nline 2'. Pour que cela fonctionne, vous devez limiter le séparateur de mots avant de l’analyser:

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

... et puis, puisque vous changez le séparateur, vous n'avez pas besoin de convertir le \n à space, vous pouvez donc le simplifier pour:

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

Cette approche fonctionnera sauf si$x contient un motif globbing correspondant (tel que "* ") - auquel cas il sera remplacé par le (s) nom (s) de fichier correspondant (s). Les méthodes read/readarray nécessitent des versions plus récentes de bash, mais fonctionnent dans tous les cas.

87
Sir Athos