Sed wraps some lines, not all

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

   
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

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

sed -i 's/h/h\n/g' infile

,
2) then, I added the the tab delimiter

    sed -i '/.$/N; s/.\n/\t/' infile

It works but strangely, not everywhere. This is the output I get

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.

try this in your 2nd step:

 sed -ir  ':a;N; $!ba; s/.\n/\t/g' infile

---------- Post updated at 01:01 ---------- Previous update was at 00:58 ----------

n and N doesn't start next cycle automatically. so a label is needed here.

---------- Post updated at 01:06 ---------- Previous update was at 01:01 ----------

or you could write

 sed -r  '/.$/{N;N;N;s/.\n/\t/g;} '
1 Like

Here's my crack at it, although if you're working with huge files, it might not be a great idea to load that much into the Hold buffer:

sed -n '1h;2,$H;${g;s/\n/\t/g;s/\tReceiver/\nReceiver/g;p}' infile

Or in shell:

#! /bin/bash
while read line; do
    [[ "$line" =~ PowerOnHours ]] && { 
        printf '%s\n' "$line"
    } || {
        printf '%s\t' "$line"
    }
done <infile
1 Like
xargs -n4 < infile |sed 's/  */\t/g'
1 Like

Elegant solution, Rdcwayx!

Some versions of sed do not support the \t syntax.

This should work on all platforms:

xargs -n4 < file | tr " " "\t"

Both suggestions worked great! I don't even have to add a newline after the PowerOnHours field (no added value, really). Your solution with bash is very straightforward, perfect for my big files.

---------- Post updated at 09:43 AM ---------- Previous update was at 09:41 AM ----------

I respectfully disagree. This suggestion gives me the following output

Receiver    ID    =    028908221899
Serial    Number    =    WD-WCASU6774998
Current    temp    =    37C
PowerOnHours    =    17434h    

Not what I am looking for.

LivinFree got it right though. Check out his solution.:slight_smile: This is what I was looking for:

Receiver ID   = 028935846791    Serial Number = WD-WCAV90944398 Current temp  = 51C     PowerOnHours  = 8896h
Receiver ID   = 028938701381    Serial Number = WD-WCAV91967340 Current temp  = 47C     PowerOnHours  = 6856h
Receiver ID   = 028938656577    Serial Number = WD-WCAV91257990 Current temp  = 48C     PowerOnHours  = 7670h

Thanks guys, you're all aces!!