0

I am trying to loop over a variable which contains newlines in a POSIX compatible way.

The following works:

echo "$REQUIRE_PURPOSE" | while IFS= read -r line ; do
  echo "$line"
done

but the piping spawns another shell.

I then tried:

OLDIFS="$IFS"
IFS='
'
for line in "$REQUIRE_PURPOSE"; do
  echo "$line"
done
IFS="$OLDIFS"

But it just prints the content of "$REQUIRE_PURPOSE"

I also tried:

while IFS= read -r line ; do
  echo "$line"
done <<< "$REQUIRE_PURPOSE"

but also here it does not work.

Example:

echo "$REQUIRE_PURPOSE"
echo "---"
while IFS= read -r line ; do echo "$line"; done <<< "$REQUIRE_PURPOSE"

generates:

uuu
iii
Digital Signature
---
uuuniiinDigital Signature

or

00000000  75 75 75 0a 69 69 69 0a  44 69 67 69 74 61 6c 20  |uuu.iii.Digital |
00000010  53 69 67 6e 61 74 75 72  65 0a 2d 2d 2d 0a 31 20  |Signature.---.1 |
00000020  75 75 75 6e 69 69 69 6e  44 69 67 69 74 61 6c 20  |uuuniiinDigital |
00000030  53 69 67 6e 61 74 75 72  65 0a 75 75 75 0a 69 69  |Signature.uuu.ii|
00000040  69 0a 44 69 67 69 74 61  6c 20 53 69 67 6e 61 74  |i.Digital Signat|
00000050  75 72 65 0a                                       |ure.|
00000054

Any idea?

8
  • The code while ... do ... done <<< "$REQUIRE_PURPOSE" works for me. What problem do you have?
    – Bodo
    Jun 17 at 12:27
  • @bodo I get just one loop iteration. macOS with bash 5.1.16(1)-release (I added the example to the question)
    – Matteo
    Jun 17 at 12:36
  • I successfully tested it with Git Bash on Windows and bash on Linux (armv7l, Raspberry PI). How do you set the value of REQUIRE_PURPOSE? Can you add code that sets the variable? Did you intentionally use read -a instead of read -r in the code below "Example:"?
    – Bodo
    Jun 17 at 12:44
  • Does your variable contain a sequence of \ and n instead of real linefeed characters?
    – Bodo
    Jun 17 at 12:45
  • @Bodo: according to hexdump is 0a (nl)
    – Matteo
    Jun 17 at 12:49

1 Answer 1

0

The option to read you need is -a. It will parse the input by IFS into the array:

read -a lines <<<"$REQUIRE_PURPOSE"
for i in "${lines[@]}"
do
    echo "$i"
done
3
  • Is there a POSIX compatible way?
    – Matteo
    Jun 17 at 12:27
  • ITYM IFS=$'\n' read -a arr -d '' <<< "$var", since you need to have the -d separator distinct from the IFS separator. Though you'd probably be better off using readarray/mapfile there, just mapfile -t arr <<< "$var" would do.
    – ilkkachu
    Jun 17 at 13:42
  • @Matteo, <<< already isn't standard. Also note that it adds a trailing newline, so you might get an extra one at the end.
    – ilkkachu
    Jun 17 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.