使用bash脚本和sed修复报价转义

use*_*971 1 bash sed

我有一个处理一些CSV的bash文件.某些输入CSV格式不正确,所以我想用sed修复它们.报价是像\"和不一样转义的"",所以我打电话给sed来改变它.在命令行中,这非常有效:

sed -i 's/\\"/""/gi' input.csv
Run Code Online (Sandbox Code Playgroud)

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

Tho*_*mas 5

你需要逃避转义字符\才能工作:

$ echo 'bla;\"bli bli\";otherbla' | sed -e 's/\\\"/""/g'
bla;""bli bli"";otherbla
Run Code Online (Sandbox Code Playgroud)

对于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
Run Code Online (Sandbox Code Playgroud)

一种解决方案是不在脚本中使用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
Run Code Online (Sandbox Code Playgroud)

然后,指出到的意见,以避免重挫并引述领域完成由错误的替代\,我们可以使用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
Run Code Online (Sandbox Code Playgroud)

如果你有几个sed命令,你可以把它放在一个脚本中,它的工作方式是一样的:

$ cat s.sed 
s/\\\"/""/g
Run Code Online (Sandbox Code Playgroud)

使用它:

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

sed -f s.sed test.csv > test-tmp.csv
Run Code Online (Sandbox Code Playgroud)