sed替换指定行号特定列号的值

5
我有一个包含5列的csv文件(以空格分隔),如下所示:
username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled 20130310 disabled

我正在尝试更改username4的第四列的值。
我的脚本已经获取了行号和要存储到username4的新值:因此,我想将第四列的值替换为$newValue,行号为$lineNumber
在我的示例中:
newValue=anything
lineNumber=4

这样它就会呈现出来:
username1 20130310 enabled 20130310 enabled
username2 20130310 enabled 20130321 disabled
username3 20130320 disabled 20130321 enabled
username4 20130310 disabled anything disabled

我计划使用sed而不是awk,因为使用sed可以通过-i进行行内更改。

你已经尝试过什么了? - Mike Gardner
2个回答

15

这里有一种方法:

$ 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

但是因为 sed-i 选项而避免使用 awk 不是一个好的理由。awk 更适合处理这种类型的问题。

$ 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

使用 awk,您可以轻松进行字段比较和编辑,使用 shell 变量不会成为引用的噩梦,并且与 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

2
这可能适用于你(GNU Sed 和 Bash):
lineNumber=4 newValue=xxxx sed -i ${lineNumber}'s/\S\+/'"${newValue}"'/4' file

然而要注意。如果newValue包含/,则需要将替换命令分隔符更改为其他字符,例如s@\S\+@${newValue}@4


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接