如何使用 sed/awk 替换逗号分隔字符串中的第 n 列/字段?

Posted

技术标签:

【中文标题】如何使用 sed/awk 替换逗号分隔字符串中的第 n 列/字段?【英文标题】:How to replace the nth column/field in a comma-separated string using sed/awk? 【发布时间】:2012-04-07 22:50:24 【问题描述】:

假设我有一个字符串

"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 '

感谢您的帮助!

【问题讨论】:

【参考方案1】:

这可能对你有用:

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

【讨论】:

如果将“NEW”分配给一个变量怎么办?这不起作用:sed 's/[^,]*/$var/'$index @dcdum2018 注意双引号。 我尝试了这些:echo $line | awk -F, -v OFS=, -v INDEX=$index '$INDEX="$var"; print'echo $line | sed 's/[^,]*/$var/'$index,但实际上两者都替换为 $var @dcdum2018 单引号可防止插值,因此要么使用双引号,要么将 shell 变量放在单引号之外,例如sed "s/[^,]*/$var/$index" file1sed 's/[^,]*/'$var'/'$index file 效果很好!谢谢!如果不是很多,你能在这里看看我的问题吗? :) ***.com/questions/69751857/…【参考方案2】:

让 shell 在 awk 程序中插入索引:

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

请注意最初的单引号 awk 程序是如何分成三部分的,单引号开头的 '$'、内插的索引值,然后是程序的单引号剩余部分。

【讨论】:

您可以使用-v var=value通过命令行在awk中定义一个变量,然后使用$var。所以不需要这个文本替换技巧。【参考方案3】:

这是打破awkwardness 的seductive 方法:

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

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

【讨论】:

如何将换行符转换回逗号分隔的列表?我试过 sed 's/\n/,/g' 但不行吗? @PeterMeier,我认为它不起作用,因为sed 现在将行分开处理,而不是整个文本。看过this answer后,我建议将输出通过管道传输到paste -sd ',',如下所示:echo "1,2,3,4" | sed 's/,/\n/g' | sed -e $index's/.*/NEW/' | paste -sd ','【参考方案4】:
# This should be faster than awk or sed.
str="1,2,3,4"
IFS=','
read -a f <<< "$str"
f[2]='NEW'
printf "$f[*]"

【讨论】:

【参考方案5】:

使用普通 awk(即不是 gawk 等)我相信您必须使用 split( string, array, [fieldsep] ); 更改选择的数组条目,然后将它们与 sprintf 或类似的循环连接在一起。

gawk 允许您将变量作为字段名称,在您的示例中为 $index。见here.

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

【讨论】:

以上是关于如何使用 sed/awk 替换逗号分隔字符串中的第 n 列/字段?的主要内容,如果未能解决你的问题,请参考以下文章

sed/awk:每隔 n 个字符插入逗号

如何在bash脚本中使用Bash / Sed / Awk / Perl删除分隔字符串的最后一个元素[duplicate]

用 TextField 中的小数分隔符替换逗号

三剑客(sed awk head)

如何使用 vim 命令或 sed/awk 命令将具有不同列数的行分隔到另一个文件中? [关闭]

如何使用 sed/awk 或其他工具辅助查找和替换 12GB 的颠覆转储文件