5

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

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

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

我的脚本已经获取了要存储的行号和新值username4:所以我想用$newValueat line number替换第 4 列的值$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

4

2 回答 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

但是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
于 2013-03-21T20:20:15.567 回答
2

这可能对您有用(GNU sed 和 Bash):

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

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

于 2013-03-22T11:36:51.370 回答