user10254032
user10254032

Reputation: 193

rearrange from specific string into respective column

I'm trying to rearrange from specific string into respective column. etc:

126N (will be sorted into "Normal" column)
Value 1 (the integer will be concatenated with 126)

Resulting :

N=Normal
126 @ 1

Here is the input

(N=Normal, W=Weak)
Value 1
126N,
Value 3
18N,
Value 4
559N, 562N, 564N,
Value 6
553W, 565A, 553N,
Value 5
490W,
Value 9
564N,

And the output should be

W=Weak
490 @ 5
553 @ 6

A=Absolute
565 @ 6

N=Normal
126 @ 1
18 @ 3
559 @ 4
562 @ 4
564 @ 4
553 @ 6
564 @ 9

Let me know your thought on this.

I've tried this script, I'm still figuring out to concatenating the value

cat input.txt | sed '/^\s*$/d'  | awk 'BEGIN{RS=","};match($0,/N/){print $3"c"$2}' | sed ':a;N;$!ba;s/\n/;/g' | sed 's/W//g;s/N//g;s/S//g' 

And some of it, are missing

Upvotes: 1

Views: 82

Answers (3)

Jotne
Jotne

Reputation: 41460

This should give you what you want using gnu awk
IT will work with any number of letters, not just A N W

awk -F, '
!/Value/ {
    for (i=1;i<NF;i++) {
        hd=substr($i,length($i),1);
        arr[hd][++cnt[hd]]=($i+0" @ "f)}
    }
    {split($0,b," ");f=b[2];} 

END {  
    for (i in arr)  { print "\n"i"\n---";
        for (j in arr[i]) {
            print  arr[i][j]}}
}' file


A
---
565 @ 6

N
---
562 @ 4
564 @ 4
553 @ 6
564 @ 9
126 @ 1
18 @ 3
559 @ 4

W
---
553 @ 6
490 @ 5

Upvotes: 2

Ed Morton
Ed Morton

Reputation: 204099

$ cat tst.awk
NR%2 { val = $NF; next }
{
    for (i=1; i<=NF; i++) {
        num  = $i+0
        abbr = $i
        gsub(/[^[:alpha:]]/,"",abbr)
        list[abbr] = list[abbr] num " @ " val ORS
    }
}
END {
    n = split("Weak Absolute Normal",types)
    for (i=1; i<=n; i++) {
        name = types[i]
        abbr = substr(name,1,1)
        print abbr "=" name ORS list[abbr]
    }
}

.

$ awk -f tst.awk file
W=Weak
553 @ 6
490 @ 5

A=Absolute
565 @ 6

N=Normal
126 @ 1
18 @ 3
559 @ 4
562 @ 4
564 @ 4
553 @ 6
564 @ 9

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84579

Another alternative in awk would be:

awk -F',| ' '
    $1 == "Value" {value = $2; next} 
    { for (i=1; i<=NF; i++) {
        if ($i~"N$")
            N[substr($i, 1, length($i) - 1)] = value
        if ($i~"W$") 
            W[substr($i, 1, length($i) - 1)] = value
      }
    }
    END {
        print "W=Weak"
        for (i in W)
            print i, "@", W[i]
        print "\nN=Normal"
        for (i in N)
            print i, "@", N[i]
    }
' file

(note: this relies on knowing the wanted headers are W=Weak and N=Normal. If would take a few additional expression if the headers are subject to change.)

Output

$ awk -F',| ' '
>     $1 == "Value" {value = $2; next}
>     { for (i=1; i<=NF; i++) {
>         if ($i~"N$")
>             N[substr($i, 1, length($i) - 1)] = value
>         if ($i~"W$")
>             W[substr($i, 1, length($i) - 1)] = value
>       }
>     }
>     END {
>         print "W=Weak"
>         for (i in W)
>             print i, "@", W[i]
>         print "\nN=Normal"
>         for (i in N)
>             print i, "@", N[i]
>     }
> ' file
W=Weak
490 @ 5

N=Normal
18 @ 3
126 @ 1
559 @ 4
562 @ 4
564 @ 9

Upvotes: 1

Related Questions