sed:如何替换\ 0,但不是\\ 0

时间:2013-08-12 12:49:34

标签: regex sed backslash

我正在从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专家都在帮忙吗?

3 个答案:

答案 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'