在Mac OSx上使用sed将列名添加到csv?

时间:2015-11-29 23:39:50

标签: macos sed prepend

我有一个像这样的csv文件:

0,0,1
1,1,0

请注意,它没有列名。在开头写下列名?我查看了问题here,但这不适用于我的Mac OSx:sed '1s/^/<column names>\n&/g'。它只是添加列名称,并附加n。我该如何实现这一目标?

2 个答案:

答案 0 :(得分:2)

如果您真的只想在现有文件中添加一行,那么cat就是您所需要的:

echo 'ColHdr1,ColHdr2,ColHdr3' | cat - file.csv > /tmp/$$ && mv /tmp/$$ file.csv

或者,更有效,但可能更加模糊,使用group command

{ echo 'ColHdr1,ColHdr2,ColHdr3'; cat file.csv; } > /tmp/$$ && mv /tmp/$$ file.csv

注意需要写入temp。首先是文件,因为shell不支持使用>的简单输出重定向读取和写回同一文件(输出文件在命令执行之前被截断)。

也就是说,shellter's answer指向更方便的解决方案,使用sed的{​​{1}}选项进行(有限的)就地更新(如果支持):

  • OS X和BSD系统(假定为-ibashksh):

    zsh
  • Linux(GNU sed -i '' $'1i\\\nColHdr1,ColHdr2,ColHdr3\n' file.csv ):

    sed
用于就地更新的

sed -i '1iColHdr1,ColHdr2,ColHdr3' file.csv 是POSIX标准的非标准扩展,它的实现方式带来了风险,最明显的是可能破坏符号链接。这同样适用于上面的-i方法。

至于为什么你的方法不起作用

> /tmp/$$ && mv /tmp/$$ ...

暂且不说:使用全局匹配的sed '1s/^/<column names>\n&/' # Fails on OS X: Sed doesn't support \n in the replacement 选项没有任何意义,因为您匹配行的开头(g),所以根据定义只能有一个匹配。

OS X 使用 BSD Sed 不支持^函数调用的替换部分中的控制字符转义序列< / strong>(与 GNU Sed不同,它确实如此)。

与上述解决方案一样,您可以使用s$'...'bash中的ANSI C-quoted stringksh)解决问题:< / p>

zsh

请注意sed $'1s/^/<column names>\\\n&/' file.csv 所需的额外\\ - 逃避\凭借ANSI C引用扩展到的文字换行符串。 (需要转义,因为文字换行通常会终止函数调用。)

或者在Sed脚本中使用 literal 换行符 - 但请注意\n - 仍然需要转义换行符:

\

以上是ANSI C引用的字符串解决方案有效扩展到的目的。

如果您想了解更灵活的GNU Sed和BSD Sed之间的所有差异,请参阅my answer here

答案 1 :(得分:1)

任何sed都会尊重i\(插入)命令。

尝试

 sed '1i\
        ColHdr1,ColHdr2,ColHdr3

 ' csv.file

<强>输出

ColHdr1,ColHdr2,ColHdr3
0,0,1
1,1,0

较新的sed并不要求您在下一行输入,因此对于某些系统

sed '1i\ColHdr1,ColHdr2,ColHdr3

 ' csv.file

因为您可以使用i\在文件中插入多行,所以必须用空行表示输入结束。

IHTH