LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Closed Thread
  Search this Thread
Old 01-23-2018, 05:12 AM   #1
Swathi Prasad
LQ Newbie
 
Registered: Jan 2018
Posts: 17

Rep: Reputation: Disabled
Linux command to delete the last non empty line from a file


Hi ,

Code:
$ cat  file1
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
Total number of rows: 5
<<Blank line >>
<<Blank line >>
<<Blank line >>
I want to delete the last non empty line(Total number of rows: 5) from the file and copy the remaining lines to new file(file2)

File 2 should be:

Code:
$ cat  file2
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
<<Blank line >>
<<Blank line >>
<<Blank line >>
I tried with the below command
Code:
sed '$d' file1>file2
But the above command instead deleting the last line and copying to the new file,like below.

Code:
$ cat  file2
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
Total number of rows: 5
<<Blank line >>
<<Blank line >>
I am new to Linux and seeking help from the forum.

Thanks.
 
Old 01-23-2018, 07:25 AM   #2
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 26,652

Rep: Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970Reputation: 7970
Quote:
Originally Posted by Swathi Prasad View Post
Hi ,
Code:
$ cat  file1
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
Total number of rows: 5
I want to delete the last non empty line(Total number of rows: 5) from the file and copy the remaining lines to new file(file2) File 2 should be:
Code:
$ cat  file2
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21
I tried with the below command
Code:
sed '$d' file1>file2
But the above command instead deleting the last line and copying to the new file,like below.
Code:
$ cat  file2
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
PGW|PGW_CDR_|2017-06-23 141946|2017-07-17 131633|2017-08-21 
Total number of rows: 5
<<Blank line >>
<<Blank line >>
I am new to Linux and seeking help from the forum.
The sed command you posted only does one thing; delete the last line of a file. If you're talking about more complex operations, like examining that line to see if it's blank, and copying/appending output to a different file, you will have to write a small script to do so. Read the "Question Guidelines" link in my posting signature...there are many easily-found bash scripting tutorials that can help you get started, but we aren't going to write your scripts for you.

To give you a hint, this:
Code:
[ -z "$line" ] && continue
..is a small bash-script line that will check the variable ($line) to see if it's empty and if so, skip it.
 
Old 01-23-2018, 07:35 AM   #3
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
If the line always contains the same text, you could use grep -v to remove it from output as well
 
Old 01-23-2018, 07:42 AM   #4
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
I think I'd like to know if it is adamant that those blank lines remain.

However brutish it is, re-use the original sed command to remove the file's last line until it is done.

Or better yet, I'm sure there's a form of sed which can first remove all blank lines.

Then use that original command to remove the last line of the file.

Quick web search Using sed to delete empty lines gives me the following suggestion:
Code:
$ sed '/^$/d' /tmp/data.txt > /tmp/output.txt
Also in that result is a command to search for and remove based on a pattern, thus if that one line with it's summary comments is desired to be removed, then find something unique in that, search for that pattern, and remove the line matching that pattern.
 
Old 01-23-2018, 08:39 AM   #5
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,374

Rep: Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754
Sometimes it helps to read last to first.
Code:
tac file1 | awk '!NF {print ""};NF {if (n) {print} else {n=1}}' | tac > file2

Last edited by allend; 01-23-2018 at 09:05 AM.
 
2 members found this post helpful.
Old 01-23-2018, 09:36 AM   #6
fatmac
LQ Guru
 
Registered: Sep 2011
Location: Upper Hale, Surrey/Hants Border, UK
Distribution: Mainly Devuan, antiX, & Void, with Tiny Core, Fatdog, & BSD thrown in.
Posts: 5,499

Rep: Reputation: Disabled
Open it with vi, & use dd to delete that line, save it to file2.
 
Old 01-23-2018, 12:24 PM   #7
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,780

Rep: Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213Reputation: 2213
How messy it's going to be depends on whether the file contains other blank lines besides the ones at the end. If there are none, then the task is pretty straightforward with awk or perl, doable with some difficulty with sed (the sed language is, after all, Turing-complete).

If there are embedded blank lines, then processing the lines in reverse order is the only single-step solution that comes to mind. (Multi-step method: Pre-process the file to locate the trailing blank lines, then use sed to delete the specific line number that precedes them.)
 
Old 01-23-2018, 04:06 PM   #8
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,131

Rep: Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121Reputation: 4121
.... and of course it depends on what one considers "blank lines" ...
 
Old 01-23-2018, 04:23 PM   #9
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,804

Rep: Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203Reputation: 1203
The following does it in one stroke
Code:
awk 'NR>1 && /./ { print buf; buf=rs=""} { buf=(buf rs $0); rs=RS } END { if (i=index(buf,RS)) print substr(buf,i+1) }' file1
The END section is only needed if trailing empty lines must be retained.
Regarding empty versus blank,
/./ means non-empty, replace it with
NF for non-blank
 
1 members found this post helpful.
Old 01-23-2018, 08:04 PM   #10
Swathi Prasad
LQ Newbie
 
Registered: Jan 2018
Posts: 17

Original Poster
Rep: Reputation: Disabled
It is working sir!

Could you please decode the command and explain.

Thanks in advance.
 
Old 01-23-2018, 08:54 PM   #11
Swathi Prasad
LQ Newbie
 
Registered: Jan 2018
Posts: 17

Original Poster
Rep: Reputation: Disabled
It is working

Quote:
Originally Posted by allend View Post
Sometimes it helps to read last to first.
Code:
tac file1 | awk '!NF {print ""};NF {if (n) {print} else {n=1}}' | tac > file2

It is working ,but could you please decode and explain.
 
Old 01-23-2018, 08:56 PM   #12
Swathi Prasad
LQ Newbie
 
Registered: Jan 2018
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by MadeInGermany View Post
The following does it in one stroke
Code:
awk 'NR>1 && /./ { print buf; buf=rs=""} { buf=(buf rs $0); rs=RS } END { if (i=index(buf,RS)) print substr(buf,i+1) }' file1
The END section is only needed if trailing empty lines must be retained.
Regarding empty versus blank,
/./ means non-empty, replace it with
NF for non-blank

It is fine,could you please decode and explain
 
Old 01-23-2018, 10:28 PM   #13
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,374

Rep: Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754Reputation: 2754
Quote:
It is working ,but could you please decode and explain.
Quote:
tac file1 | awk '!NF {print ""};NF {if (n) {print} else {n=1}}' | tac > file2
The tac command is like cat, but reads in reverse, last line to first line.
The awk command sets an internal variable NF containing the number of fields when it reads a line. The ! is the NOT operator, so !NF is true when no fields are found in the line and an empty line is printed.
When an awk variable is initialised without a value, it defaults to zero, so n=0. When the first line containing fields is found, then n is set to 1 and nothing is printed. Subsequently all lines containing fields are printed.

I will let MadeInGermany explain his clever creation manipulating the record separator variable in conjunction with a buffer.
 
1 members found this post helpful.
Old 01-23-2018, 10:29 PM   #14
giis
Member
 
Registered: Nov 2013
Location: Third Rock from Moon
Distribution: RPM/DEB based and LFS
Posts: 73

Rep: Reputation: Disabled
You can also use grep. Just search for lines beginning (^) with required word (PGW) and redirect the output to new file.

Quote:
grep ^PGW /path/to/original.txt > new_file.txt
 
Old 01-24-2018, 12:39 AM   #15
Swathi Prasad
LQ Newbie
 
Registered: Jan 2018
Posts: 17

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by allend View Post
The tac command is like cat, but reads in reverse, last line to first line.
The awk command sets an internal variable NF containing the number of fields when it reads a line. The ! is the NOT operator, so !NF is true when no fields are found in the line and an empty line is printed.
When an awk variable is initialised without a value, it defaults to zero, so n=0. When the first line containing fields is found, then n is set to 1 and nothing is printed. Subsequently all lines containing fields are printed.

I will let MadeInGermany explain his clever creation manipulating the record separator variable in conjunction with a buffer.

What difference does it make if the code is changed to (I need to understand it as my sas code is not allowing the double codes,but the functionality if the code should not change) as below.
Code:
tac file1 | awk '!NF {print};NF {if (n) {print} else {n=1}}' | tac > file2
as per my understanding it does not make any difference,Am I correct?

Thanks in advance
 
  


Closed Thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: How To Empty a File, Delete N Lines From a File, Remove Matching String From a File, And Remove Empty/Blank Lines From a File In Linux LXer Syndicated Linux News 0 11-22-2017 12:30 PM
[SOLVED] Script/Command to delete a line from a text file when a column value is null Buddhike G Programming 8 06-13-2014 02:03 AM
vi delete empty line? Junior_DBA Linux - Newbie 5 09-11-2008 03:21 PM
how do i create an empty bash(.sh) file in command line? bbmak Linux - Newbie 1 10-26-2007 02:39 AM
vim how to delete until the first empty line edenCC Linux - Software 2 05-03-2007 10:26 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 11:50 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration