2012-03-23 66 views
7

假设我有一个字符串如何使用sed/awk替换逗号分隔字符串中的第n列/字段?

"1,2,3,4" 

现在我要替换,如字符串的第三个字段由一些不同的值。

"1,2,NEW,4" 

我设法用下面的命令来做到这一点:

echo "1,2,3,4" | awk -F, -v OFS=, '{$3="NEW"; print }' 

现在被替换列的索引应变量传递。所以在这种情况下,

index=3 

我怎么能通过这个awk?因为这不起作用:

echo "1,2,3,4" | awk -F, -v OFS=, '{$index="NEW"; print }' 
echo "1,2,3,4" | awk -F, -v OFS=, '{$($index)="NEW"; print }' 
echo "1,2,3,4" | awk -F, -v OFS=, '{\$$index="NEW"; print }' 

感谢您的帮助!

回答

5

有壳的awk程序插值指数:

echo "1,2,3,4" | awk -F, -v OFS=, '{$'$index'="NEW"; print }' 

注意原来单引号awk程序是如何在三个部分裂开,一个单引号开始“{$”,插值索引值,然后是该程序的单引号剩余部分。

+1

您可以使用'-v var = value'通过命令行在awk中定义一个变量,然后使用'$ var'。所以这个文本替换黑客是不需要的。 – Kaz 2012-03-24 18:30:37

-1

使用普通awk(I.E.非gawk等)我相信你将不得不使用split(string, array, [fieldsep]);改变数组入口的选项,然后将它们与sprintf或类似的回路一起循环使用。

gawk允许你在你的例子中有一个变量作为字段名称$ index。请参阅here.

gawk通常是Linux上的默认awk,因此将您的调用更改为gawk“script”并查看它是否有效。

4

这可能会为你工作:

index=3 
echo "1,2,3,4" | awk -F, -v OFS=, -v INDEX=$index '{$INDEX="NEW"; print }' 

或:

index=3 
echo "1,2,3,4" | sed 's/[^,]*/NEW/'$index 
1

这里是打破awk wardness一个sed uctive方式:

$ echo "1,2,3,4" | sed 's/,/\n/g' | sed -e $index's/.*/NEW/' 

这是很容易地扩展到多个索引只需增加另一个-e $newindex's/.*/NEWNEW/'

+0

如何将换行符转换回逗号分隔列表?我试过sed's/\ n /,/ g'但那不行? – 2012-03-23 12:55:40

+0

@PeterMeier,我认为它不起作用,因为'sed'现在分开处理行,而不是整个文本。看了[这个答案](http://stackoverflow.com/a/6539865/1258041),我建议管道输出到'paste -sd',''像这样:'echo“1,2,3,4 “| sed's /,/ \ n/g'| sed -e $ index的/.*/ NEW /'| paste -sd',''。 – 2012-03-23 17:48:22

0
# This should be faster than awk or sed. 
str="1,2,3,4" 
IFS=',' 
read -a f <<< "$str" 
f[2]='NEW' 
printf "${f[*]}"