2

Basically I'd like to split a string into an array by a string separator like sep. for example. Is there native bash way to do this without using tools like sed, awk, etc? I know I can split a string into an array by setting IFS and using read -ra but that doesn't work with string separators. And if there is not how you'd do it with tools like sed, awk, etc?

Let's say I have the string This is some sep.string and I'd like to split it into an array with 2 elements: This is some and string.

2
  • 1
    There may actually some way to do that directly, but you could just replace the multi-character separator with a character which doesn't appear in the string: foo='a sep b sep c'; s=$'\1'; IFS=$s read -ra <<<"${foo//sep/$s}" array; printf "{%s}\n" "${array[@]}"
    – user313992
    Jun 5, 2019 at 18:46
  • Will your array ever have more than two elements?
    – jesse_b
    Jun 5, 2019 at 19:14

2 Answers 2

1

You could manually iterate through the variable with parameter expansion:

#!/bin/bash
var='This is some sep.string
with
newlines
sep.another line'

a=()
while [[ $var =~ sep\. ]]
do
  e=${var%%sep.*}
  a+=("${e}")
  var=${var#${e}sep.}
done
a+=("${var}")

This loops over the variable (updating it in the process), stripping off the first separator onwards (%% looks for the longest match, so this will track backwards from the end of the string until the first instance of sep.); it adds that remainder into the array then strips that remainder and the separator off from the front of the variable. Iterate until the variable does not contain a separator any more, then add any remainder into the array.

1

Sort of a native way to do it using both parameter expansion and readarray

string='This is some sep.string'
mapfile -t array < <( echo "${string//sep./$'\n'}" )

${string//sep./$'\n'} - Will replace occurrences of sep. with a newline. mapfile/readarray will create an array with each line in it's own element.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .