我想简单地更改CSV上的分隔符。 该文件来自外部服务器,因此分隔符是这样的:^ A。
name^Atype^Avalue^A
john^Ab^A500
mary^Ac^A400
jack^Ad^A200
我想得到这个:
name,type,value
john,b,500
mary,c,400
jack,d,200
我需要将其更改为逗号(,)或制表符(,),但我的sed命令,尽管输出正确,但不会写入文件。
cat -v CSVFILE | sed -i "s/\^A/,/g"
当我使用上面的行时,它正确输出用逗号分隔的文件而不是^ A,但它不会写入文件。
我也尝试过这样:
sed -i "s/\^A/,/g" CSVFILE
也不起作用...... 我做错了什么?
答案 0 :(得分:2)
文字 ^A
(两个字符,^
和A
)是cat -v
可视化的方式< / em>控制字符0x1
(ASCII代码1
,名为SOH
(标题的开头))。 ^A
是caret notation到代表不可打印的ASCII字符的示例:
^A
代表键盘组合 Control-A ,当前面是通用转义序列 Control-V 时,就是如何创建终端中的实际控制字符;换句话说,
Control-V Control-A 将插入一个实际的0x1
字符。
顺便说一句,插入符号(^<letter>
)的逻辑是:字母对应于所表示的控制字符的ASCII值;例如,A
对应0x1
,D
对应0x4
(^D
,EOT
)。
换句话说:将0x40
添加到控制字符的ASCII值中,以符号表示法获取其字母表示的ASCII值。
^@
代表NUL
(0x0
字符)而^?
代表DEL
(0x7f
)与此符号一致,因为{{1}具有ASCII值@
(即,它出现在ASCII表中的0x40
(A
之前)并且0x41
约束为7位(与...进行位与运算)最大ASCII值0x40 + 0x7f
)产生0x7f
,这是0x3f
的ASCII值。
要检查给定文件中<异或控制字符的 ASCII值 ,您可以将其管道传输到?
,表示od -c
为(八进制)0x1
。
这意味着直接将文件传递给001
时,您不能使用插入符号,而必须使用实际控制字符您sed
来电中的<> 。
s
字符时,它还会< em>以插入符号表示 - 作为0x1
- 但在这种情况下,它只是终端对真实控制字符的可视化;虽然它可能看起来像两个可打印的字符^A
和^
,但它不是。纯粹在视觉上你无法区分 - 这就是为什么使用转义序列或ANSI C引用的字符串来表示控制字符是更好的选择 - 见下文。假设您的shell为A
,bash
或ksh
,则更好的替代方法是使用 Control-V Control-A 是使用ANSI C-quoted string生成zsh
字符:0x1
$'\1'
也会识别sed
的转义序列\x01
。< / LI>
因此,您的命令应该是:
0x1
或使用ANSI C引用的字符串:
sed -i 's/\x01/,/g' CSVFILE # \x01 only recognized by GNU sed
注意:虽然此表单原则上可以与 BSD / OSX sed -i $'s/\1/,/g' CSVFILE
一起使用,但sed
语法略有不同:您必须使用-i
使用sed -i '' $'s/\1/,/g' CSVFILE
执行任务的唯一原因是利用就地更新(sed
);否则,-i
是更好的选择 - 请参阅Ed Morton's answer。
答案 1 :(得分:1)
如果您的sed
支持-i选项,则可以像这样使用它:
sed -i.bak -e "s/\^A/,/g" CSVFILE
(这假定源文件中的分隔符由两个字符^和A组成;如果^ A应该引用Control-A,则必须相应地进行调整,例如使用's/\x01/,/g'
。 )
否则,假设您要保留原始文件的副本(例如,如果结果不符合您的预期 - 请参阅下文),可以使用以下咒语:
mv CSVFILE CSVFILE.bak && sed "s/\^A/,/g" CSVFILE.bak > CSVFILE
正如其他地方所指出的,如果源文件分隔符是Control-A,您还可以使用tr '\001' ,
(或tr '\001' '\t'
作为标签页。)
需要注意的是,源文件中的分隔符可能会被精确使用,因为逗号可能出现在&#34;值&#34;分隔符是分开的。如果这是可能的话,那么将需要一种不同的方法。 (参见例如https://tools.ietf.org/html/rfc4180)
答案 2 :(得分:1)
这是创建的作业tr
:
tr '<control-A>' ',' < file > tmp && mv tmp file
显然用文字控件-A替换<control-A>
。
答案 3 :(得分:0)
如果它在OS X下运行:
在-i
添加扩展程序以写入新文件:
sed -i.bak "s/^A/,/g" CSVFILE
或写到位:
sed -i '' "s/^A/,/g" CSVFILE
您也可以使用cat输出到文件但在sed上没有-i
命令:
cat -v CSVFILE | sed "s/^A/,/g" > ouput
确保以这种方式写^ A:
控制 + V + 控制 + A