1

I've been doing some research on how to correctly read lines from a file whose last line may not have a trailing newline character. Have found the answer in Read a line-oriented file which may not end with a newline.

However, I have a second goal that is to exclude the comments at the beginning of lines and have found a grep command that achieves the goal

$ grep -v '^ *#' file

But I have noticed that this command has a (for me unexpected) side behavior: it adds a trailing newline character in the last line if it does not exist

$ cat file
# This is a commentary
aaaaaa
# This is another commentary
bbbbbb
cccccc

$ od -c file
0000000   #       T   h   i   s       i   s       a       c   o   m   m
0000020   e   n   t   a   r   y  \n   a   a   a   a   a   a  \n   #
0000040   T   h   i   s       i   s       a   n   o   t   h   e   r
0000060   c   o   m   m   e   n   t   a   r   y  \n   b   b   b   b   b
0000100   b  \n   c   c   c   c   c   c  \n
0000111

$ truncate -s -1 file

$ od -c file
0000000   #       T   h   i   s       i   s       a       c   o   m   m
0000020   e   n   t   a   r   y  \n   a   a   a   a   a   a  \n   #
0000040   T   h   i   s       i   s       a   n   o   t   h   e   r
0000060   c   o   m   m   e   n   t   a   r   y  \n   b   b   b   b   b
0000100   b  \n   c   c   c   c   c   c
0000110

$ od -c <(grep -v '^ *#' file)
0000000   a   a   a   a   a   a  \n   b   b   b   b   b   b  \n   c   c
0000020   c   c   c   c  \n
0000025

Notice that besides removing the line beginning comments it also adds a trailing newline character in the last line.

How could that be?

1

1 Answer 1

0

The POSIX specifications states that

A line is a sequence of zero or more non-<newline> characters plus a terminating
<newline> character.

The behaviour of grep is the expected one. It adds the missing trailing newline character to the incomplete line.

This way:

$ cat file
# This is a commentary
aaaaaa
# This is another commentary
bbbbbb
cccccc

$ od -c file
0000000   #       T   h   i   s       i   s       a       c   o   m   m
0000020   e   n   t   a   r   y  \n   a   a   a   a   a   a  \n   #
0000040   T   h   i   s       i   s       a   n   o   t   h   e   r
0000060   c   o   m   m   e   n   t   a   r   y  \n   b   b   b   b   b
0000100   b  \n   c   c   c   c   c   c  \n
0000111

$ truncate -s -1 file

$ od -c file
0000000   #       T   h   i   s       i   s       a       c   o   m   m
0000020   e   n   t   a   r   y  \n   a   a   a   a   a   a  \n   #
0000040   T   h   i   s       i   s       a   n   o   t   h   e   r
0000060   c   o   m   m   e   n   t   a   r   y  \n   b   b   b   b   b
0000100   b  \n   c   c   c   c   c   c
0000110

$ od -c <(grep '.' file)
0000000   #       T   h   i   s       i   s       a       c   o   m   m
0000020   e   n   t   a   r   y  \n   a   a   a   a   a   a  \n   #    
0000040   T   h   i   s       i   s       a   n   o   t   h   e   r    
0000060   c   o   m   m   e   n   t   a   r   y  \n   b   b   b   b   b
0000100   b  \n   c   c   c   c   c   c  \n
0000111

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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