Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

In various places around the web I've found:

\015 
\012
\x0a - hex
\n
\r

all as synonyms for various newlines / carriage returns...

But in this small script I cannot recognise when I come across a newline - can someone tell me what I should be checking for in the if line ?

#!/bin/bash

test="this is a
test"

for a in "$test"; do

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

echo "$a"

done
share|improve this question
1  
I have a dumb question. Why do you need to do this? If you read input line by line cat | while read line; do ...; done, you know there was a carriage return for each iteration. If your input can be files with \r without \n, just transform the file tr '\r' '\n' while processing the input. If you just need to know if there are multiple lines: wc -l. –  nicerobot Dec 22 '11 at 20:14
    
Welcome to Stack Exchange. Please don't edit your question this way, as it makes the existing answers meaningless. Since you've found a way to solve your problem, you may post it as an alternate answer. –  Gilles Dec 22 '11 at 23:40
    
@nicerobot if there is no newline at all, then wc -l will return 0; you should add that as an answer –  Arcege Dec 23 '11 at 2:10
    
@lolfrog the solution should not be in the question, you should mark the answer which has the solution –  Arcege Dec 23 '11 at 2:16

3 Answers 3

up vote 5 down vote accepted

If you directly use strings under a for loop, it will work per-word, not per-character. You need to use a while loop with read in order to parse letter-by-letter. Or introduce a numerical parameter that would iterate over the string.

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

Here's a working version:

#!/bin/bash

test="this is a
test"

echo -n "$test" | while IFS= read -N 1 a; do

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

printf "$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 \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.

share|improve this answer
    
In short, it is turning the quoted escape sequence like \n into its byte representation, so that you don't need to place ugly-looking, quoted line breaks in your test statement. –  rozcietrzewiacz Dec 22 '11 at 14:31

I'd suggest using tr and then test:

if [ -n "$(tr -cd '\n\r' < datafile)" ]; then
    echo "NEWLINE FOUND"
fi

The tr -cd removes everything except the newlines/carriage returns. If there are newlines in the file, then there will be output from which the -n test will return true.

share|improve this answer

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 [[ )
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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