How to discover a new line using a for loop?

If you directly use strings under a for loop, it will work per-word (here on one word: the whole content of $test since it's quoted), not per-character. You need to use a while loop with read in order to parse letter-by-letter, or to introduce a numerical parameter that would iterate over the string.

In addition, when using read, you need to make sure that newlines and whitespaces aren't interpreted as delimiters and to force read to read one char at a time.

Here's a working version:

#!/bin/bash

test="this is a
test"

printf %s "$test" | while IFS= read -r -N 1 a; do

        if [[ "$a" == $'\n' ]] ; then
                echo "FOUND NEWLINE"
        fi

printf %s "$a"

done

You could replace $'\n' with $'\012' or $'\x0a', since they all represent the same newline code. But it is not the same as \015 or \r - this stands for carriage return (return to the beginning of line). On Linux systems, newlines are represented using \n, but on Windows for example, they are represented by a sequence of \r\n instead. That is why if you had a text file from Windows, you could detect newlines also by searching for \r.


You can check for newlines in a variable very easily in bash with:

[[ $var = *$'\n'* ]]

I find it more convenient to use:

declare -r EOL=$'\n' TAB=$'\t' # at top of script
..
if [[ $var = *$EOL* ]]; then # to test (no field-splitting in [[ )

Tags:

String

Shell

Bash