Search code examples
linuxbashshifs

How to split break lines with Bash scripts?


If you have a string with a delimiter, let's say a , character, you could use IFS just like that:

text=some,comma,separated,text
IFS="," read -ra ADDR <<< "$text"

for i in ${ADDR[@]}
do
    echo $i
done

Each word will be printed in a new line. But if you grab the result of command like ls and then try to split it on the \n you don't get to the same result:

results=$(ls -la)
IFS="\n" read -ra ADDR <<< "$results"

for i in ${ADDR[@]}
do
    echo $i
done

It only prints 2 lines, and they are not even the file entries. It is

total
36

The first line of the ls command output.

Can someone give a little help? If it is not the correct way, how is that?


Solution

  • read usually reads until it reaches newline, unless you tell it otherwise using -d.

    In this example, we use -d $'\0'. This has the shell read until it reaches a null character (which it won't in the output of ls). Then IFS=$'\n' causes the shell to split on newline and assign each line as an array element. Note the use of $'...' instead of "..." to interpret the escape sequences.

    results=$(ls -la)
    
    IFS=$'\n' read -ra ADDR -d $'\0' <<< "$results"
    
    for i in "${ADDR[@]}"
    do
        echo "$i"
    done
    

    Last but not least, we have to quote both the substitutions of the array and $i.