sed replace in-line a specific column number value

2019-03-21 07:39发布

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

标签: linux shell sed
2条回答
迷人小祖宗
2楼-- · 2019-03-21 07:53

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
查看更多
We Are One
3楼-- · 2019-03-21 08:06

This might work for you (GNU sed & Bash):

lineNumber=4 newValue=xxxx sed -i ${lineNumber}'s/\S\+/'"${newValue}"'/4' file

However beware. If the newValue contains a / you will need to change the substitute command delimiter to something else e.g. s@\S\+@${newValue}@4

查看更多
登录 后发表回答