Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trailing newlines and the bash 'read' builtin

In bash, this works:

echo -n $'a\nb\nc\n' | while read x; do echo = $x =; done

The while loops through three times

= a =
= b =
= c =

But imagine a text file that doesn't have the conventional trailing newline. I think that read should still work for all three lines, but it doesn't. I just get:

echo -n $'a\nb\nc' | while read x; do echo = $x =; done

= a =
= b =

The help read in bash doesn't really clarify.

Note: I don't need this resolved, and I can see some ways to fix it myself. I am curious, and I am tempted to file a bug report - I generally try myself to respect files that mightn't have the trailing new line. I came across this when using the -d option to read. read -d " " will split on spaces instead of newlines, but it will miss out on the last entry unless it has a trailing space.

(Ubuntu. GNU bash, version 4.1.5(1)-release)

like image 739
Aaron McDaid Avatar asked Dec 22 '11 02:12

Aaron McDaid


People also ask

What flag can be used with Echo to disable output of the trailing newline?

When the -n option is used, the trailing newline is suppressed. If the -e option is given, the following backslash-escaped characters will be interpreted: \\ - Displays a backslash character. \a - Alert (BEL)

How do you echo without newline?

The best way to remove the new line is to add '-n'. This signals not to add a new line. When you want to write more complicated commands or sort everything in a single line, you should use the '-n' option.

How do you echo a new line?

There are a couple of different ways we can print a newline character. The most common way is to use the echo command. However, the printf command also works fine. Using the backslash character for newline “\n” is the conventional way.


1 Answers

If you want the above loop to process the incomplete line, do this:

echo -n $'a\nb\nc' | while read x || [[ $x ]]; do echo = $x =; done

which gives:

= a =
= b =
= c =

When read encounters the incomplete line, it does read that into the variable (x in this case) but returns a non-zero exit code which would end the loop, and || [[ $x ]] takes care of running the loop for the incomplete line as well. When read is called the next time, there is nothing to read and it exits with 1, setting x to an empty string as well, which ensures that we end the loop.


Related

  • Looping through the content of a file in Bash
like image 164
codeforester Avatar answered Sep 23 '22 13:09

codeforester