Reputation: 31
I have a csv file, with student name and marks. I want to update "marks" of a student with name "jack"(the only person in the csv). the data in csv file looks as below.
student,marks
jack,10
peter,20
rick,10
I found this awk '$1 == "Audrey" {print $2}' numbers.txt, but iam not sure on how to modify the file.
Upvotes: 1
Views: 4059
Reputation: 84642
Another approach with sed
is to anchor the replacement to the digits at the end of the line with:
sed '/^jack,/s/[0-9][0-9]*$/12/' file
This uses the form sed '/find/s/match/replace'
where find
locates at the beginning of the line '^'
the word "jack,"
eliminating all ambiguity with, e.g. jackson,33
. Then the normal substitution form of 's/match/replace/'
where match
locates at least one digit at the end of the line (anchored by '$'
) and replaces it with the 12
(or whatever you choose).
Example Use/Output
With your example file in file
, you would have:
$ sed '/^jack,/s/[0-9][0-9]*$/12/' file
student,marks
jack,12
peter,20
rick,10
(note: the POSIX character class of [[:digit:]]
is equivalent to [0-9]
which is another alternative)
The equivalent expression using the POSIX character class would be:
sed '/^jack,/s/[[:digit:]][[:digit:]]*$/12/' file
You can also use Extended Regular Expression which provides the '+'
repetition operator to indicate one-or-more compared to the basic repetition designator of '*'
to indicate zero-or-more. The equivalent ERE would be sed -E '/^jack,/s/[0-9]+$/12/' file
You can add the -i
option to edit in-place and/or using it as -i.bak
to create a backup of the original with the .bak
extension before modifying the original.
Upvotes: 0
Reputation: 204638
awk 'BEGIN{FS=OFS=","} $1=="jack"{$2=27} 1' foo.csv > tmp && mv tmp foo.csv
Upvotes: 3
Reputation: 52644
ed
is usually better for in-place editing of files than sed
:
printf "%s\n" "/^jack,/c" "jack,${new_grade}" "." w | ed -s input.csv
or using a heredoc to make it easier to read:
ed -s input.csv <<EOF
/^jack,/c
jack,${new_grade}
.
w
EOF
At the first line starting with jack,
, change it to jack,XX
where XX
is the value of the new_grade
variable, and write the new contents of the file.
Upvotes: 1
Reputation: 31
It worked for me with
sed -ir "s/^\(jack\),.*/\1,$new_grade/"
input.csv. with argument "r" or else i get the "error sed: 1: "input.csv": command i expects \ followed by text".
Upvotes: 1
Reputation: 7657
You could use sed:
new_grade=9
sed -i'' "s/^\(jack\),.*/\1,$new_grade/"
The pattern ^\(jack\),.*
matches the beginning of the line ^
followed by jack
by a comma and the rest of the line .*
. The replacement string \1,$new_mark
contains the first captured group \1
(in this case jack
) followed by a comma and the new mark.
Alternatively you could loop over the file and use a pattern substitution:
new_grade=9
while read -s line; do
echo ${line/jack,*/jack,$new_grade}
done < grades.txt > grades2.txt
Upvotes: 0