sed替换特定行号的内联特定列号值

时间:2013-03-21 20:17:14

标签: linux shell sed

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

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

我正在尝试更改username4的第4列的值。

我的脚本已获取行号和要为username4存储的新值:所以我想将第4列值替换为第$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进行内联更改

2 个答案:

答案 0 :(得分:14)

这是一种方式:

$ 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

但是,由于awk具有sed选项而避免使用-i并不是一个好理由。 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

答案 1 :(得分:1)

这可能适合你(GNU sed& Bash):

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

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