Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed replace in-line a specific column number value at a specific line number

Tags:

linux

shell

sed

I have a 5 columns csv file (space separated) like this :

username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled 20130310 disabled

I'am trying to change the value of the 4th column for username4.

My script already gets the line number and the new value to store for username4 : so I would like to replace column 4 value with $newValue at line number $lineNumber.

In my sample:

newValue=anything
lineNumber=4

So that it will render:

username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled anything disabled

I plan to use sed instead of awk because with sed we can do in-line changes with -i

like image 640
user2196728 Avatar asked Mar 21 '13 20:03

user2196728


1 Answers

Here is one way:

$ sed '/^username4/{s/ [^ ]*/ anything/3}' file
username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled anything disabled

# store changes back to the file 
$ sed -i '/^username4/{s/ [^ ]*/ anything/3}' file

But avoiding awk because sed has the -i option isn't a good reason. awk is more suited to working with this kind of problem.

$ awk '$1=="username4"{$4="anything"}1' file
username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled anything disabled

# store changes back to the file
$ awk '$1=="username4"{$4="anything"}1' file > tmp && mv tmp file

With awk you can easily do field comparison and editing, using shell variable isn't a quoting nightmare and understanding scripts you wrote only yesterday isn't and issue unlike with sed:

$ linenumber=4

$ newvalue=anything 

$ awk 'NR==n{$4=a}1' n=$linenumber a=$newvalue file 
username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled anything disabled

$ awk 'NR==n{$4=a}1' n=$linenumber a=$newvalue file > tmp && mv tmp file
like image 97
Chris Seymour Avatar answered Oct 10 '22 02:10

Chris Seymour