2012-10-05 46 views
1

我有一个bash文件处理一些CSV。某些输入CSV格式不正确,所以我想用sed修复它们。引号是像\"那样转义的,而不是像"",所以我打电话给sed来改变它。在命令行中,这是完美的作品:修复引用转义与bash脚本和sed

sed -i 's/\\"/""/gi' input.csv 

但是在一个bash脚本中,这似乎什么都不做。我想这与引用和转义序列有关,但解决方案是什么?

+4

请注意,您的命令行有点问题。虽然它可能适用于GNU sed,但它会在其他环境中抛出错误,因为'-i'选项是用于备份文件的扩展。为了解决这个问题,请明确指出命令行的哪一部分是脚本。 'sed -i -e's/\\“/”“/ gi'input.csv' – ghoti

回答

5

你需要躲避转义字符\对于工作:

$ echo 'bla;\"bli bli\";otherbla' | sed -e 's/\\\"/""/g' 
bla;""bli bli"";otherbla 

对于bash脚本,你需要确保你从CSV文件中读取线正确引用传递给sed的时。你能提供一个CSV文件的例子,以及你如何从文件中读取?

使用cat file | while read,这里是问题的一个示例:

$ cat test.csv 
bla;\"bli bli\";otherbla 
ble;""bli bli"";otherbla 
bli;\"blo\";otherbla 

$ cat test.sh 
#!/bin/bash 

cat test.csv | while read line; 
do echo "$line" | sed -e 's/\\\"/""/g' 
done 

$ ./test.sh 
bla;"bli bli";otherbla 
ble;""bli bli"";otherbla 
bli;"blo";otherbla 

一种解决方案是在脚本中不使用回声而是直接在文件中使用SED和存储所产生的CSV在一个新的文件:

$ sed -e 's/\\\"/""/ig' test.csv > test-tmp.csv 
$ cat test-tmp.csv 
bla;""bli bli"";otherbla 
ble;""bli bli"";otherbla 
bli;""blo"";otherbla 

然后,指出到的意见,以避免重挫并引述领域的\整理的错更换,我们可以使用2个SED表达式,包括外地分离,以确保我们更换Ø NLY之前或之后的字段分隔\"(在我的例子中,字段分隔符是;),但这一个没有考虑到如blo线与该领域的一个\作为最后一个字符引用帐户字段单:

$ cat test.csv 
bla;\"bli bli\";otherbla 
ble;""bli bli"";otherbla 
bli;\"blo\";otherbla 
blo;"bli bli\";otherbla 
blu;""bli bli\"";otherbla 

$ sed -e 's/;\\\"/;""/ig' -e 's/\\\";/"";/ig' test.csv 
bla;""bli bli"";otherbla 
ble;""bli bli"";otherbla 
bli;""blo"";otherbla 
blo;"bli bli"";otherbla 
blu;""bli bli\"";otherbla 

如果你有几个sed命令,你可以把一个脚本,它的工作方式相同:

$ cat s.sed 
s/\\\"/""/g 

使用它:

$ echo 'bla;\"bli bli\";otherbla' | sed -f s.sed 
bla;""bli bli"";otherbla 

sed -f s.sed test.csv > test-tmp.csv 
+1

你将如何避免以反斜杠结尾的结尾字段(并且在引用时以backslaah-doublequote结尾)?这种解决方案可以只有当你知道没有这样的数据时才会被应用,否则,你犯了一个你不能撤消的错误(通过先备份数据来保存)。 – itsbruce

+0

奇怪。'echo'bla; \“bli bli \”; otherbla' | sed -e's/\\“/”“/ g''也可以在bash脚本中使用。 – choroba

+1

@choroba这个作品,因为我们能够简单的报价'''逃跑的路线,然而,读取文件时,你最终与其中,echo'ed时,只能用双引号“''逃脱的变量 – Thomas

3

您是否考虑过其中一个字段合法以\字符结尾的情况? CSV文件中的带引号的表示将以反斜杠结尾并加上引号结尾; sed解决方案,比如你的和托马斯的将会破坏它。

这就是为什么sed是使用带引号的csv的错误工具;有些问题只能用适当的语言(awk,Perl或其他)递归地解决。

+1

是的,我知道,幸运的是这个作品 - 无论如何都是暂时的 – user694971