我有一个像这样的csv文件:
0,0,1
1,1,0
请注意,它没有列名。在开头写下列名?我查看了问题here,但这不适用于我的Mac OSx:sed '1s/^/<column names>\n&/g'
。它只是添加列名称,并附加n
。我该如何实现这一目标?
答案 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系统(假定为-i
,bash
或ksh
):
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 string(ksh
)解决问题:< / 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