我有一个bash文件处理一些CSV。某些输入CSV格式不正确,所以我想用sed修复它们。引号是像\"
那样转义的,而不是像""
,所以我打电话给sed来改变它。在命令行中,这是完美的作品:修复引用转义与bash脚本和sed
sed -i 's/\\"/""/gi' input.csv
但是在一个bash脚本中,这似乎什么都不做。我想这与引用和转义序列有关,但解决方案是什么?
我有一个bash文件处理一些CSV。某些输入CSV格式不正确,所以我想用sed修复它们。引号是像\"
那样转义的,而不是像""
,所以我打电话给sed来改变它。在命令行中,这是完美的作品:修复引用转义与bash脚本和sed
sed -i 's/\\"/""/gi' input.csv
但是在一个bash脚本中,这似乎什么都不做。我想这与引用和转义序列有关,但解决方案是什么?
你需要躲避转义字符\
对于工作:
$ 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
您是否考虑过其中一个字段合法以\字符结尾的情况? CSV文件中的带引号的表示将以反斜杠结尾并加上引号结尾; sed解决方案,比如你的和托马斯的将会破坏它。
这就是为什么sed是使用带引号的csv的错误工具;有些问题只能用适当的语言(awk,Perl或其他)递归地解决。
是的,我知道,幸运的是这个作品 - 无论如何都是暂时的 – user694971
请注意,您的命令行有点问题。虽然它可能适用于GNU sed,但它会在其他环境中抛出错误,因为'-i'选项是用于备份文件的扩展。为了解决这个问题,请明确指出命令行的哪一部分是脚本。 'sed -i -e's/\\“/”“/ gi'input.csv' – ghoti