使用bash脚本和sed修复引号转义



我有一个bash文件处理一些CSV。有些输入CSV的格式不正确,所以我想用sed修复它们。引号像"一样转义,而不像"",所以我调用sed来更改这一点。在命令行中,这非常有效:

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

但在bash脚本中,这似乎毫无作用。我想这与引号和转义序列有关,但解决方案是什么?

您需要转义符才能工作:

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

对于bash脚本,在将其传递给sed时,需要确保从CSV文件中读取的行被正确引用。你能提供一个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

一种解决方案是不在脚本中使用echo,而是直接在文件中使用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表达式,并包括字段分隔符,以确保我们仅替换字段分隔符之前或之后的"(在我的示例中,字段分隔符为;),但此分隔符不考虑以作为字段中最后一个字符的单引号字段,如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或其他任何语言)递归地解决

相关内容

  • 没有找到相关文章

最新更新