Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Awk/Perl/Sed column substitution based on a text code

Tags:

sed

awk

perl

I have a text file with the following content

L,4m,06/03/2013
L,33GJm,06/03/2013,G
L,44Bm,06/03/2013,B
L,4q,08/03/2013
J,4m,04/03/2013
J,3GU,04/03/2013,G
J,3jm,04/03/2013
J,3GJ,04/03/2013,G
J,44Bm,06/03/2013,B
J,34Bq,08/03/2013,B
M,4v,12/03/2013
D,3GU,12/03/2013,G
D,4B,11/03/2013,B
D,4m,12/03/2013
D,3GJ,13/03/2013,G
D,3GU,13/03/2013,G
D,4B,14/03/2013,B
D,4B,14/03/2013,B
D,34Bm,14/03/2013,B
L,33BUq,11/03/2013,B
L,3BJUq,11/03/2013,B
L,44Bq,14/03/2013,B
L,44Bq,14/03/2013,B
L,3Bq,15/03/2013,B
L,3q,15/03/2013
J,34Bjq,11/03/2013,B
J,33GUm,12/03/2013,G
J,4q,13/03/2013
J,33GUq,13/03/2013,G
J,33GUq,13/03/2013,G
J,4q,13/03/2013
M,3BU,18/03/2013,B
M,4B,18/03/2013,B
M,4B,18/03/2013,B
M,3GJ,19/03/2013,G
M,3GJ,19/03/2013,G
D,4B,22/03/2013,B
D,3BU,22/03/2013,B
L,34Bv,18/03/2013,B
L,3jm,19/03/2013
L,4m,19/03/2013
L,33GJm,19/03/2013,G
L,33GUm,19/03/2013,G
J,33BUm,18/03/2013,B
J,4m,18/03/2013
J,4B,18/03/2013,B
J,33BUm,18/03/2013,B
J,4q,22/03/2013
J,4q,22/03/2013
A,3GJ,28/03/2013,G
M,4B,27/03/2013,B
D,4B,25/03/2013,B
L,44Bq,25/03/2013,B
L,34Bq,25/03/2013,B
L,34Bq,25/03/2013,B
L,33BUa,26/03/2013,B
L,33BUq,26/03/2013,B
L,33BUq,26/03/2013,B
L,34Bq,27/03/2013,B
L,34Bq,27/03/2013,B
L,4B,27/03/2013,B
L,34Bq,27/03/2013,B
L,4a,28/03/2013

I want to translate the second column based on the following coding system.

If $2 starts with a 1 or 2 - Change $2 to Excellent If $2 contains 3BU or 3GU - Change $2 to Good if $2 contains 3BJ or 3GJ - Change $2 to OK If $2 starts with a 4 - Change $2 to Poor If $2 starts with a 5 - Change $2 Terrible

I can find and change the 3BUs to Good easy enough using the following command

awk 'BEGIN{FS=",";OFS=","} {if ($2~ /3(B|G)U/)print $1,"Good",$3}' file | sponge file

Though I use all other non 3(B|G)U lines. I could use if else terminology though this seems inelegant. I have tried to use gensub to solve the problem

awk -F, '{gensub(/3(B|G)U/,Good,"",2)}1' file

But this prints the file contents without substitution. Any hints

Desired output

L,Poor,06/03/2013
L,Ok,06/03/2013,G
L,Poor,06/03/2013,B
L,Poor,08/03/2013
J,Poor,04/03/2013
J,Good,04/03/2013,G

A perl or sed one-liner would also be helpful as this code forms part of a bash shell script

like image 245
moadeep Avatar asked May 04 '26 05:05

moadeep


1 Answers

If you want to stick with shell:

(
    IFS=,
    while read -ra f; do     # pick more appropriate variable names
        case ${f[1]} in
            [12]*)    f[1]=Excellent ;;
            *3[BG]U*) f[1]=Good ;;
            *3[BG]J*) f[1]=OK ;;
            4*)       f[1]=Poor ;;
            5*)       f[1]=Terrible ;;
        esac
        echo "${f[*]}"
    done < file
) > tmp && mv tmp file

I ran that in a subshell to localize changes to $IFS

like image 89
glenn jackman Avatar answered May 07 '26 07:05

glenn jackman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!