1

I want split the string with delimiter comma and write it to a file. I have the below script but when I see the output(temp.txt) I see the complete for loop code written to file.. Can anyone help me to fix this issue

#!/bin/bash -e

string1=a/b,b/c,c/d

IFS=', ' read -a array <<< "$string1"

cat << 'EOF' > temp.txt
for element in "${array[@]}"
do
    echo "$element"
done
EOF

Expected file temp.txt output

a/b
b/c
c/d

3 Answers 3

2

Use printf:

#!/bin/bash -e
string1=a/b,b/c,c/d
IFS=', ' read -ra array <<< "$string1"
printf '%s\n' "${array[@]}" > temp.txt

And the longer way:

for e in "${array[@]}"; do
    echo "$e"
done > temp.txt

Another using IFS:

IFS=$'\n' eval 'echo "${array[*]}" > temp.txt'

Note: Changing the IFS is unnecessary but if you want to strictly split the string with commas, change it to IFS=,:

IFS=, read -ra array <<< "$string1"
Sign up to request clarification or add additional context in comments.

1 Comment

+1; starts out with the best-practices printf approach and shows a series of additional correct answers (with the caveat that the echo version wouldn't work correctly with -E or -n as data on account of bash's non-POSIX behavior). Also, this is interesting to me as a demonstration of a place where eval is entirely safe and useful.
1

Your IFS is incorrect, there should be no space. Also, you can just indirect the output of the loop to the file:

#!/bin/bash -e

string1=a/b,b/c,c/d

IFS=',' read -a array <<< "$string1"
for element in "${array[@]}"
do
    echo "$element"
done > temp.txt

If your only intention is to turn commas into newlines, you could use something simple like tr:

tr , '\n' <<<"$string1" > temp.txt

1 Comment

+1 I was wondering what is space doing in all the answers and the question.
1

You could also use the -d option of the read builtin command in a loop like this:

while read -d, -r; do
    echo "$REPLY"
done <<<"$string1," > temp.txt

You'll notice that I added a , to the end of the string1 expansion as -d is substituting , for a newline character.

Although it requires a bit more code, you could avoid adding the extra comma to the here string by doing another echo $REPLY after the loop.

{ while read -d, -r; do
      echo "$REPLY"
  done <<<"$string1"
  echo $REPLY
} > temp.txt

You could also just use a subshell to echo your array with a newline IFS:

IFS=, read -ra array <<<"$string1"
(IFS=$'\n'; echo -e "${array[*]}") > temp.txt

1 Comment

Without the trailing comma you just have to use $REPLY one more time after the loop ends (because read returns non-zero on EOF). Though that's likely less useful of a pattern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.