关于linux:为什么sed不能使用国际字符,并且如何解决?

关于linux:为什么sed不能使用国际字符,并且如何解决?

Why does sed fail with International characters and how to fix?

GNU sed version 4.1.5似乎因国际字符而失败。 这是我的输入文件:

1
2
3
Gras Och Stenar Trad - From Moja to Minneapolis DVD [G2007DVD] 7812 | X

Gras Och Stenar Trad - From M?ja to Minneapolis DVD [G2007DVD] 7812 | Y

(请注意第二行的变音符号。)

当我这样做

1
sed 's/.*| //' < in

我希望只看到XY,因为我已要求删除直到'|'的所有字符以及超出它的空间。 相反,我得到:

1
2
X
Gras Och Stenar Trad - From M? Y

我知道我可以使用tr删除国际字符。 首先,但是有一种方法只能使用sed吗?


我认为如果文件的输入编码与环境的首选编码不同,则会发生错误。

示例:in是UTF-8

1
2
3
4
5
6
$ LANG=de_DE.UTF-8 sed 's/.*| //' < in
X
Y
$ LANG=de_DE.iso88591 sed 's/.*| //' < in
X
Y

UTF-8可以安全地解释为ISO-8859-1,您会得到奇怪的字符,但除此之外一切都很好。

示例:in是ISO-8859-1

1
2
3
4
5
6
$ LANG=de_DE.UTF-8 sed 's/.*| //' < in
X
Gras Och Stenar Trad - From M?Y
$ LANG=de_DE.iso88591 sed 's/.*| //' < in
X
Y

ISO-8859-1无法解释为UTF-8,解码输入文件失败。 奇怪的匹配可能是由于sed试图恢复而不是完全失败的事实。

答案基于Debian Lenny / Sid,版本为4.1.5。


对于非ASCII文本,sed的设置不是很好。 但是,您可以(几乎)在perl中使用相同的代码并获得所需的结果:

1
perl -pe 's/.*\\| //' x


推荐阅读