Sorting with sed,awk ...

I need to sort this input using sed, awk or any other tool to give below output

Input:

RXOCF-8              

CLASS 2A
57

RU
40

RXORX-8-0            

CLASS 1B
 23 45 16

RXORX-8-1            

EXTERNAL CLASS 2A
 6

RXOCF-21             

RXOTX-34-1           

CLASS 1B
 2

desired output:

RXOCF-8 CLASS 2A:57 RU 40
RXORX-8-0 CLASS 1B:23 CLASS 1B:45 CLASS 1B:16
RXORX-8-1 EXTERNAL CLASS 2A:6 
RXOCF-21
RXOTX-34-1 CLASS 1B:2 

Here is one approach:

>cat rxocf.txt
RXOCF-8

CLASS 2A
57

RU
40

RXORX-8-0

CLASS 1B
 23 45 16

RXORX-8-1

EXTERNAL CLASS 2A
 6

RXOCF-21

RXOTX-34-1

CLASS 1B
 2

>cat rxocf.txt | sed 's/RXO/~RXO/' | tr -d "\n" | tr -s " " | tr "~" "\n"

RXOCF-8 CLASS 2A57RU40
RXORX-8-0 CLASS 1B 23 45 16
RXORX-8-1 EXTERNAL CLASS 2A 6
RXOCF-21
RXOTX-34-1 CLASS 1B 2

Here's one way to do it with Perl:

$
$ # show the contents of the data file
$ cat -n f0
     1  RXOCF-8
     2
     3  CLASS 2A
     4  57
     5
     6  RU
     7  40
     8
     9  RXORX-8-0
    10
    11  CLASS 1B
    12   23 45 16
    13
    14  RXORX-8-1
    15
    16  EXTERNAL CLASS 2A
    17   6
    18
    19  RXOCF-21
    20
    21  RXOTX-34-1
    22
    23  CLASS 1B
    24   2
$
$
$ ##
$ perl -ne 's/^\s*//; s/\s*$//; chomp;
>           if (/./) {
>             if (/^RX/ and $x) {
>               print "$str\n";
>               $str = $_;
>             } elsif (/^RX/) {
>               $x = 1;
>               $str .= $_;
>             } elsif (/CLASS/) {
>               $prfx = "$_:";
>             } elsif ($prfx) {
>               @arr = split/ /;
>               $str .= " $prfx".join(" $prfx", @arr);
>               $prfx = "";
>             } else {
>               $str .= " $_";
>             }
>           }
>           END {print $str,"\n"}
>          ' f0
RXOCF-8 CLASS 2A:57 RU 40
RXORX-8-0 CLASS 1B:23 CLASS 1B:45 CLASS 1B:16
RXORX-8-1 EXTERNAL CLASS 2A:6
RXOCF-21
RXOTX-34-1 CLASS 1B:2
$
$

tyler_durden

Slightly modified:

$
$ ##
$ perl -ne 's/^\s*//; s/\s*$//; chomp;
>           if (/./) {
>             if (/^RX/ and $x) {print "$str\n"; $str = $_}
>             elsif (/^RX/) {$x = 1; $str .= $_}
>             elsif (/CLASS/) {$prfx = "$_:"}
>             elsif ($prfx) {s/^|[ ]+/ $prfx/g; $str .= $_; $prfx=""}
>             else {$str .= " $_"}
>           } END {print $str,"\n"}' f0
RXOCF-8 CLASS 2A:57 RU 40
RXORX-8-0 CLASS 1B:23 CLASS 1B:45 CLASS 1B:16
RXORX-8-1 EXTERNAL CLASS 2A:6
RXOCF-21
RXOTX-34-1 CLASS 1B:2
$
$
 awk '/^RXO/{if(s!="")print s;s=$1" ";next}{s=s""$0}END{if(s!="") print s}' infile

Hi, aydj:

$ cat aydj.awk 
function p() {if (s) {gsub(/  +/, " ", s); print s}}
/^RXO/ {p(); s=$1; next}
/CLASS/ {c=$0; getline; gsub(/[^ ]+/, c":&"); s=s" "$0; next}
{s=s" "$0}
END {p()}

$ awk -f aydj.awk data
RXOCF-8 CLASS 2A:57 RU 40 
RXORX-8-0 CLASS 1B:23 CLASS 1B:45 CLASS 1B:16 
RXORX-8-1 EXTERNAL CLASS 2A:6 
RXOCF-21 
RXOTX-34-1 CLASS 1B:2

Cheers,
Alister

can you explain this part?

 gsub(/[^ ]+/, c":&");

especially the usage of ^ and &

/[^ ]+/ matches any sequence of one or more non-space characters (the leading ^ complements the class).

The & in the replacement string expands to whatever was matched by the regular expression, in this case: /[^ ]+/

So, if the value of c is "CLASS 1B", and the current record is "23 45 16", this gsub command converts the current record into "CLASS 1B:23 CLASS 1B:45 CLASS 1B:16"

Hope that helps.

Best Wishes,
Alister

Thanks! Excellent, it worked.

---------- Post updated at 04:42 AM ---------- Previous update was at 02:56 AM ----------

How can i get this output:

RXOCF-8 CFCLASS 2A:57 CFRU:40
RXORX-8-0 RXCLASS 1B:23 RXCLASS 1B:45 RXCLASS 1B:16
RXORX-8-1 RXEXTERNAL CLASS 2A:6 
RXOCF-21
RXOTX-34-1 TXCLASS 1B:2

I would try to fix the program that generates the original output ...

@ Alister

can you help generate an output that looks like that of aydj:

input:
ELGBS17 RXOTRX-10-6 FAULT CODE 2A
ELGBS17 RXOTRX-10-6 43
ELGBS17 RXOTRX-10-6 RU
ELGBS17 RXOTRX-10-6 0
ELGBS17 RXOTRX-218-5 FAULT CODE 2A
ELGBS17 RXOTRX-218-5 43
ELGBS17 RXOTRX-218-5 RU
ELGBS17 RXOTRX-218-5 0
EOGBS01 RXOCF-111 FAULT CODE 2A
EOGBS01 RXOCF-111 57
EOGBS01 RXOCF-111 RU
EOGBS01 RXOCF-111 40
EOGBS01 RXOCF-33 FAULT CODE 2A
EOGBS01 RXOCF-33 57
EOGBS01 RXOCF-33 RU
EOGBS01 RXOCF-33 40
EOGBS01 RXOCF-38 FAULT CODE 2A
EOGBS01 RXOCF-38 33 57
EOGBS01 RXOCF-38 RU
EOGBS01 RXOCF-38 40
EOGBS01 RXOCF-50 FAULT CODE 2A
EOGBS01 RXOCF-50 33 57
EOGBS01 RXOCF-50 RU
EOGBS01 RXOCF-50 40
EOGBS01 RXOCF-64 FAULT CODE 2A
EOGBS01 RXOCF-64 33 57
EOGBS01 RXOCF-64 RU
EOGBS01 RXOCF-64 40

output:

ELGBS17 RXOTRX-10-6 FAULT CODE 2A:43 RU 0
ELGBS17 RXOTRX-218-5 FAULT CODE 2A:43 RU 0
EOGBS01 RXOCF-111 FAULT CODE 2A:57 RU 40
EOGBS01 RXOCF-33 FAULT CODE 2A:57 RU 40
EOGBS01 RXOCF-38 FAULT CODE 2A:57 RU 40
EOGBS01 RXOCF-50 FAULT CODE 2A:33 2A:57 RU 40
EOGBS01 RXOCF-64 FAULT CODE 2A:33 2A:57 RU 40

Thanks in Advance

$ cat aydj.awk
function p() {if (s) {gsub(/  +/, " ", s); print s}}
/^RXO/ {p(); s=$1;b=substr($1,4,2); next}
/CLASS/ {c=b$0; getline; gsub(/[^ ]+/, c":&"); s=s" "$0; next}
/^RU/ {s=s b $0":";next}
{s=s" "$0}
END {p()}

$ awk -f aydj.awk data
RXOCF-8 CFCLASS 2A:57 CFRU: 40
RXORX-8-0 RXCLASS 1B:23 RXCLASS 1B:45 RXCLASS 1B:16
RXORX-8-1 RXEXTERNAL CLASS 2A:6
RXOCF-21
RXOTX-34-1 TXCLASS 1B:2

---------- Post updated 01-22-10 at 12:29 AM ---------- Previous update was 01-21-10 at 11:59 PM ----------

$ cat jagannaja.awk
function p() {if (t) {gsub(/  +/, " ", t); print t}}
/CODE/ {p(); s=$NF;$NF="";t=$0;getline;{for (i=3;i<=NF;i++) t=t" "s":"$i };next}
{t=t" "$NF}
END {p()}

$ awk -f jagannaja.awk input
ELGBS17 RXOTRX-10-6 FAULT CODE 2A:43 RU 0
ELGBS17 RXOTRX-218-5 FAULT CODE 2A:43 RU 0
EOGBS01 RXOCF-111 FAULT CODE 2A:57 RU 40
EOGBS01 RXOCF-33 FAULT CODE 2A:57 RU 40
EOGBS01 RXOCF-38 FAULT CODE 2A:33 2A:57 RU 40
EOGBS01 RXOCF-50 FAULT CODE 2A:33 2A:57 RU 40
EOGBS01 RXOCF-64 FAULT CODE 2A:33 2A:57 RU 40

Thanks, it's working.

@Alister,

Thanks!