Remove last newline character..

Hi all..

I have a text file which looks like below:

abcd
efgh
ijkl
(blank space)

I need to remove only the last (blank space) from the file. When I try wc -l the file name,the number of lines coming is 3 only, however blank space is there in the file.

I have tried options like below:

awk 'NF' file1 > file2

and some others but nothing worked out.

Please help me in solving this issue.

Thanks & Regards,
Sathya V.

try awk /./ file1

This will remove all the blank lines from the file!

[user@host ~]$ cat file
abcd
efgh
ijkl

[user@host ~]$ sed '$d' file
abcd
efgh
ijkl
[user@host ~]$

hi balajesuri..

your solutions didnt work in my case..

I guess the sample file you used has space in the last line..whereas my file is just a newline..

please suggest.

thanks..
sathya v.

This works for me

awk NF
user1@test /tmp [10:5]$ cat b
dsaf
afds
asdf

user1@test /tmp [10:5]$ awk NF b
dsaf
afds
asdf
user1@test /tmp [10:5]$

So does:

awk '/./'
awk '!/^$/'
sed '/./!d'

No, there is no space on the last line.

[user@host ~]$ cat -A file
abcd$
efgh$
ijkl$
$
[user@host ~]$

And in fact, sed '$d' file simply deletes the last line regardless of what it is.

As I mentioned in my mail when I take the count of the file, it is giving me the value without the next line. However when I open the file in vi mode the cursor goes till the line 'ijkl'. This is looking strange. Any suggestions regarding the file?

awk NF file

works fine on an Aix system but i do not understand why.
Can someone detail it ?
Thank You

dude open the file using VI editor
vi filename

after that go to the line which u want to delete, and then press esc+dd to remove the line then save it using wq! command..thats it

You could automate that using ed, of course, or any of the other solutions given.

I suspect Sathya83aa wants to have it automated, somehow.

Maybe the last line of your file has control/non-printing character(s).
Try the following command and check the ASCII code of the character(s) in the last line.

od -bc your_file_name

I am sure that if you follow Durden's suggestion, the last character contained in the file as printed by the od command will not be a newline.

From the symptoms that have been described, it is clear that this is not a text file (because the last character of a non-empty text file must be a newline character and wc -l would return 4 instead of 3). Since there are characters following the last newline character in this file, the behavior of awk, ed, sed, vi, and many other utilities is unspecified. On some implementations these utilities may add a newline to the end of the file (with or without a diagnostic or warning message), may ignore all characters following the last newline character in the file, (although probably less likely) do absolutely anything the programmer thought would be fun in this case, or (more likely) do something the programmer never considered (because (s)he never considered the possibility that the input might not be a properly formed text file).

One reliable way on any Linux or UNIX system to delete any characters following the last newline whether or not there are any is:

echo "" >> filename
printf '$d\nw\nq\n' | ed -s filename

However, even this is only guaranteed to work if there aren't any NUL bytes in the file and there aren't more than (LINE_MAX - 1) consecutive bytes in the file that do not contain a newline character. You should be able to get the value of LINE_MAX on your system by running the command:

getconf LINE_MAX
1 Like

A portable approach that can cope with any file type:

file=$1
offset=$(
    od -An -v -tu1 "$file" |
    sed 's/[[:blank:]]\{1,\}/ /g; s/^ //; s/ $//; y/ /\n/' |
    awk '$0=="10" {i=NR} END {print i+0}'
)
dd bs=1 seek=$offset if=/dev/null of="$file"

Everything after the final newline is truncated. Files without a newline are truncated to zero length. The contents of files ending in a newline are not modified.

The byte value sought could be trivially parameterized so that anything following the final occurrence of that value is discarded.

In the vast majority of cases, Don's simpler approach should suffice.

Regards,
Alister

1 Like

Nicely done Alister. But even this approach has an exception. This code will remove all characters in a file after the last <newline> character as long as the file is encoded using a codeset that is a superset of ASCII.

If you want to use this on IBM's AIX on a mainframe computer (or any other OS that uses EBCDIC to encode text), you'll need to change the $0=="10" in the awk command to $0=="37" .

1 Like

Quite right. Parameterizing the byte value along with echo | od -An -tu1 yield a solution for any character encoding with a single-byte newline (a multibyte sequence can be matched, but not without complicating the code).

Regards,
Alister