LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
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

Reply
 
Search this Thread
Old 03-16-2011, 06:25 PM   #1
kristo5747
Member
 
Registered: Jul 2010
Location: Earth
Distribution: Ubuntu 11.04 (Natty Narwhal)
Posts: 31

Rep: Reputation: 0
Sed wraps some lines, not all


Greetings. I am using SED to cleanup files that are laid out like so:

Code:
   
ReceiverID=028936004663
SerialNumber=WD-WCAV95708405
Currenttemp=44C
PowerOnHours=3663h
ReceiverID=028923894902
SerialNumber=WD-WCAV9A766701
Currenttemp=49C
PowerOnHours=2215h
My boss wants files like this one to be tab ("\t") delimited like so

Code:
ReceiverID=...(tab)SerialNumber=...(tab)Currenttemp=...(tab)PowerOnHours=...(newline)
ReceiverID=...(tab)SerialNumber=...(tab)Currenttemp=...(tab)PowerOnHours=...(newline)...
1) first, I added a newline to mark each record
Code:
sed -i 's/h/h\n/g' infile
,
2) then, I added the the tab delimiter
Code:
    sed -i '/.$/N; s/.\n/\t/' infile
It works but strangely, not everywhere. This is the output I get

Code:
ReceiverID=...(tab)SerialNumber=...(tab???)
Currenttemp=...(tab)PowerOnHours=...(newline)
ReceiverID=...(tab)SerialNumber=...(tab???)
Currenttemp=...(tab)PowerOnHours=...(newline)
What am I missing?? I welcome your input. Thanks.
 
Old 03-17-2011, 12:52 AM   #2
grail
Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 7,442

Rep: Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880Reputation: 1880
So I understand why your output is not working, but my sed-jitsu is not good enough to correct it (I am sure one of the gurus will help).

I can tell you that:

1. Your first step adds no real benefit, at least not for what happens in the second.

2. Once 'N' is called the next time through it effectively looks at the alternating odd lines.
So first time through it grabs line 2 and appends to line 1 and replaces last character plus '\n' with '\t'
On the next iteration it looks at line 3 and then calls 'N' which grabs line 4 (this is unlike your expectation that it would look at line 2 and grab line 3)

I believe you need to use the ':' and 't' looping ability, but sadly I could not find the right combinations.

However, as an alternate, here is an awk solution:
Code:
awk 'NR>1 && /Receiver/{$0="\n"$0}1' ORS="\t" file
 
Old 03-17-2011, 11:50 AM   #3
kristo5747
Member
 
Registered: Jul 2010
Location: Earth
Distribution: Ubuntu 11.04 (Natty Narwhal)
Posts: 31

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by grail View Post
So I understand why your output is not working, but my sed-jitsu is not good enough to correct it (I am sure one of the gurus will help).

I can tell you that:

1. Your first step adds no real benefit, at least not for what happens in the second.

2. Once 'N' is called the next time through it effectively looks at the alternating odd lines.
So first time through it grabs line 2 and appends to line 1 and replaces last character plus '\n' with '\t'
On the next iteration it looks at line 3 and then calls 'N' which grabs line 4 (this is unlike your expectation that it would look at line 2 and grab line 3)

I believe you need to use the ':' and 't' looping ability, but sadly I could not find the right combinations.

However, as an alternate, here is an awk solution:
Code:
awk 'NR>1 && /Receiver/{$0="\n"$0}1' ORS="\t" file
After *lots* of trials/errors, I got this (with help from people smarter than me):

Code:
#! /bin/bash
while read line; do
    [[ "$line" =~ PowerOnHours ]] && { 
        printf '%s\n' "$line"
    } || {
        printf '%s\t' "$line"
    }
done <myfile
I don't even need to add the newline after PowerOnHours (no added value, really). It gets me the output I was looking for

Code:
Receiver ID   = 028918576472    Serial Number = WD-WCAUK0635287 Current temp  = 50C     PowerOnHours  = 12972h
Receiver ID   = 028968505835    Serial Number = WD-WCAUH1726359 Current temp  = 48C     PowerOnHours  = 9591h
Thanks for your time.

Last edited by kristo5747; 03-17-2011 at 11:52 AM.
 
Old 03-17-2011, 06:59 PM   #4
crts
Senior Member
 
Registered: Jan 2010
Posts: 1,604

Rep: Reputation: 446Reputation: 446Reputation: 446Reputation: 446Reputation: 446
Hi,

I know this is solved but since you initially asked for a sed solution I thought I'll provide one:
Code:
sed -n '/ReceiverID/ {h;b};H;/PowerOnHours/ {x;s/\n/\t/g;p}' file
 
  


Reply

Tags
sed


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
[SOLVED] Remove lines with sed Stevy12 Linux - Newbie 13 03-16-2011 07:10 PM
Truncating lines using sed kmkocot Linux - Newbie 3 03-19-2010 04:07 PM
sed two lines down secretlydead Programming 2 04-24-2009 10:56 AM
Sed command to print matching lines and 2 lines above.. DX398 Programming 12 10-01-2008 08:25 AM
awk/gawk/sed - read lines from file1, comment out or delete matching lines in file2 rascal84 Linux - General 1 05-24-2006 09:19 AM


All times are GMT -5. The time now is 09:06 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration