1

If I want to read a string and split it on a given delimiter, I can set IFS and store string slices in an array. Then I can do whatever I want with its items:

while IFS=_ read -r -a myarray; do
    printf "%s -\n" "${myarray[@]}"
done <<< "a_b"

This returns:

$ while IFS=_ read -r -a myarray; do echo "hello"; printf "%s -\n" "${myarray[@]}"; done <<< "a_b"
hello
a -
b -

However, I sometimes want to read just one of these fields per loop. So I wonder if there is a way to have this while loop be fed by a slice every time. That is, on the first iteration have read get just a, on the second one just b and so on.

I found a way changing the way we feed the loop: instead <<< "a_b" I use tr to split this up by replacing every _ with a new line with < <(tr "_" "\n" <<<"a_b"):

$ while IFS=_ read -r -a myarray; do echo "hello"; printf "%s -\n" "${myarray[@]}"; done < <(tr "_" "\n" <<<"a_b")
hello
a -
hello
b -

However, I wonder: is there any other way for this? As we have IFS to change the field separators, does Bash have any other variable to set the "record separators" like awk for example has?

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 2
    could you not just use a for loop – 123 Jan 08 '16 at 11:21
  • Also you can use the `-d` option for read to treat the delimiter as an _ instead of a newline. I think this has nothing to do with bash behaviour. – 123 Jan 08 '16 at 11:34
  • 1
    `read` builtin is very limited and no where close to `awk` which supports all kind of regular expressions for `FS`, `RS` and `FPAT` variables to split the input in many ways. I don't think one can even provide multiple delimiters in `-d` option of `read` – anubhava Jan 08 '16 at 13:32

0 Answers0