我正在从mysql迁移到postgres。作为其中的一部分,我在使用sed处理mysql转储之前将其加载到postgres中。
我的MySQL转储有一些\0
个字符,而postgres不喜欢它们。所以我用空格替换它们。
sed 's/\\0/ /g' $dumpfile
当该行有320.48k\\02. Easy Listening
时出现问题。
$ echo '320.48k\\02. Easy Listening' | sed 's/\\0/ /g'
320.48k\ 2. Easy Listening
这不是我想要的。 \\
后跟0
个字符不是空字符。我想保持原样。
任何sed专家都在帮忙吗?
答案 0 :(得分:6)
如果要替换空字符(\ 0),可以使用:
sed 's/\x0/ /g'
或
tr '\0' ' '
我经常使用
tr '\0' '\n'< /proc/13217/environ
显示流程的环境
答案 1 :(得分:3)
首先,当正则表达式跟\0
\
匹配
$ echo '320.48k\\02. Easy Listening' | sed 's/\([^\\]\)\\0/\1 /g'
320.48k\\02. Easy Listening
这解决了问题,但当\0
位于行的开头时失败,所以将前一个匹配设为可选:
$ echo '\0320.48k\\02. Easy\0Listening' | sed 's/\([^\\]\)\?\\0/\1 /g'
320.48k\ 2. Easy Listening
但这不起作用,因为\\0
可以匹配正则表达式而且括号内的子组没有出现。
另一种选择是说\0
必须位于该行的开头,或者前一个字符不能是\
$ echo '\0320.48k\\02. Easy\0Listening' | sed 's/\([^\\]\|^\)\\0/\1 /g'
320.48k\\02. Easy Listening
(正如评论所指出的,对于奇数个反斜杠,这仍然会给出错误的结果。)
答案 2 :(得分:3)
请注意,\\\0
必须由\\␣
替换,依此类推。因此,除了最后一个后跟空格之外,用相同的反斜杠替换包含奇数个反斜杠后跟0
的任何序列。序列需要以非反斜杠字符或行的开头开头,否则\\0
将从第二个反斜杠开始匹配。如果有多个连续的\0
序列,则不会捕获它们,因为第一个匹配的字符是第一个反斜杠之前的字符;你需要将它们全部匹配,并用一个空格替换它们。
sed -e 's/\(\([^\]\|^\)\(\\\\\)*\)\\0\(\(\\\\\)*\\0\)*/\1 /g'
如果您的sed没有\|
,请使用两个单独的替换命令。
sed -e 's/^\(\(\\\\\)*\)\\0\(\(\\\\\)*\\0\)*/\1 /' -e 's/\([^\]\(\\\\\)*\)\\0\(\(\\\\\)*\\0\)*/\1 /g'
或者,使用Perl。它的look-behind assertion可以派上用场,说“这绝不能用反斜杠”。
perl -pe 's/(?<!\\)((?:\\\\)*)\\0/$1 /g'
在Perl中,另一种方法可能更清楚:替换每个反斜杠+字符序列,并根据以下字符计算替换文本。
perl -pe 's/\\(.)/$1 eq "0" ? " " : "\\$1"/eg'