Linux sed 在特定行号处内嵌替换特定列号值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15557206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:30:55  来源:igfitidea点击:

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

linuxshellsed

提问by user2196728

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

我有一个 5 列 csv 文件(空格分隔),如下所示:

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.

我正在尝试更改第 4 列的值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 $newValueat line number $lineNumber.

我的脚本已经获得了要存储的行号和新值username4:所以我想用$newValue行号替换第 4 列的值$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 sedinstead of awkbecause with sedwe can do in-line changes with -i

我打算使用sed而不是awk因为sed我们可以使用-i

采纳答案by Chris Seymour

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 awkbecause sedhas the -ioption isn't a good reason. awkis more suited to working with this kind of problem.

但是awk因为sed-i选择而避免并不是一个很好的理由。awk更适合处理此类问题。

$ awk '=="username4"{="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 '=="username4"{="anything"}1' file > tmp && mv tmp file

With awkyou 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:

由于awk您可以轻松地进行字段比较和编辑,因此使用 shell 变量不是一个引用噩梦,并且理解您昨天才编写的脚本并不是与问题不同的问题sed

$ linenumber=4

$ newvalue=anything 

$ awk 'NR==n{=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{=a}1' n=$linenumber a=$newvalue file > tmp && mv tmp file

回答by potong

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

这可能对你有用(GNU sed & Bash):

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

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

不过要小心。如果newValue包含 a /,则需要将替换命令分隔符更改为其他内容,例如s@\S\+@${newValue}@4