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.

Recommended Answers

All 2 Replies

In your second script the N command does join a current pattern space with the next line; however the s command causes the (updated) pattern space to be printed out. Essentially, you join pairs of lines.

My recommendation would be to use a hold buffer, and careful addressing like this:

/PowerOnHours/ !{
    # Notice the negation. Any line not matching is appended to the hold buffer
    H
}
/PowerOnHours/ {
    # Got the end of record. Append it to the hold buffer...
    H
    # ...copy the hold buffer into the pattern space...
    g
    # ...replace newlines with tabs...
    s/\n/^I/g
    # ...print out the desired result
    p
    # Finally, clear the pattern space and place an empty line in the hold buffer
    # for the next iteration.
    s/.*//
    h
}

After *lots* of trials/errors, I got this (with help from people smarter than me):

#! /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

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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.