Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash: awk to replace a string in a file

Tags:

bash

awk

I have a text based data base file which stores student entries as follows:

SID:LNAME:FNAME:hw01:quiz01
004:dravid:rahul:78:100
002:ganguly:sourav:54:13
005:kohli:virat:48:43
001:kumble:anil::54
003:tendulkar:sachin:87:78

User inputs the title he wants to update and the sid/lname/fname of the student. So, for example if user enters

sid=001, hw01, score=19, I want the output as follows:

SID:LNAME:FNAME:hw01:quiz01
004:dravid:rahul:78:100
002:ganguly:sourav:54:13
005:kohli:virat:48:43
001:kumble:anil:19:54
003:tendulkar:sachin:87:78

What I realized is awk is the best way to do this. Any idea how to do that?

Thanks.

like image 965
Rachit Agrawal Avatar asked Dec 05 '25 14:12

Rachit Agrawal


2 Answers

You can use this awk command:

awk -v sid='001' -v hw01='19' 'BEGIN {FS=OFS=":"} $1 == sid { $4 = hw01 } 1' file
SID:LNAME:FNAME:hw01:quiz01
004:dravid:rahul:78:100
002:ganguly:sourav:54:13
005:kohli:virat:48:43
001:kumble:anil:19:54
003:tendulkar:sachin:87:78

Update: As per comments below this awk command accepts search & update column names and values.

awk -v skey='SID' -v sval='001' -v ukey='hw01' -v uval='19' 'BEGIN { FS=OFS=":" }
       NR==1{for (i=1; i<=NF; i++) col[$i]=i} $col[skey]==sval{ $col[ukey]=uval } 1' file
SID:LNAME:FNAME:hw01:quiz01
004:dravid:rahul:78:100
002:ganguly:sourav:54:13
005:kohli:virat:48:43
001:kumble:anil:19:54
003:tendulkar:sachin:87:78
like image 61
anubhava Avatar answered Dec 07 '25 05:12

anubhava


$ cat tst.awk
BEGIN { FS=OFS=":" }
{
    if (NR==1) {
        for (i=1; i<=NF; i++) {
            name2num[tolower($i)] = i
        }
        # upd="sid=001,hw01=19"
        split(tolower(upd),tmp,/[=,]/)
        keyNum = name2num[tmp[1]]
        keyVal = tmp[2]
        tgtNum = name2num[tmp[3]]
        tgtVal = tmp[4]
    }
    else {
        if ($keyNum == keyVal) {
            $tgtNum = tgtVal
        }
    }
    print
}

.

$ awk -v upd="sid=001,hw01=19" -f tst.awk file
SID:LNAME:FNAME:hw01:quiz01
004:dravid:rahul:78:100
002:ganguly:sourav:54:13
005:kohli:virat:48:43
001:kumble:anil:19:54
003:tendulkar:sachin:87:78

$ awk -v upd="lname=dravid,quiz01=54" -f tst.awk file
SID:LNAME:FNAME:hw01:quiz01
004:dravid:rahul:78:54
002:ganguly:sourav:54:13
005:kohli:virat:48:43
001:kumble:anil::54
003:tendulkar:sachin:87:78
like image 35
Ed Morton Avatar answered Dec 07 '25 07:12

Ed Morton



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!