Bash: awk to replace a line in a file
I have a text database file that stores student records like this:
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
The user enters the name he wants to update and the sid / lname / fname of the student. So, for example, if the user types
sid = 001, hw01, score = 19, I want the result to be like this:
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
I figured out that awk is the best way to do this. Any idea how to do this?
Thank.
+3
source to share
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 the comments below, this awk command accepts the names and values of the search and update columns.
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
+5
source to share
$ 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
+3
source to share