【问题标题】:Will sed (and others) corrupt non-ASCII files?sed(和其他)会损坏非 ASCII 文件吗?
【发布时间】:2012-03-14 01:34:37
【问题描述】:

如果我编写一些脚本来操作文件,比如用 sed 进行搜索/替换,并且文件可以是各种字符集,那么文件会损坏吗?

我希望替换的文本是 ASCII 并且仅出现在文件中仅包含 ASCII 但其余行包含其他字符集中的字符的行上。

【问题讨论】:

  • 我的回答是你唯一的问题。但是,其他字符集似乎也可以工作。由于到目前为止您还没有在这里得到任何答案,看来您最好的选择是在其他地方搜索。
  • 您可以通过将一些文件复制到临时目录,使用 sed 修改它们,然后查看这些文件是否会破坏使用它们的程序来轻松测试这一点。祝你好运。
  • 嗯,文件太多太大,无法彻底测试。希望得到专家的意见。 :)
  • “diff”能否告诉我文件中的任何非 ASCII 内容是否已更改(逐行更改)? -a 开关是否处理非 ASCII 字符集?
  • 这些东西没有得到适当的标准化,所以一般的答案是这取决于你的平台。实际上,对于 8 位数据,Linux 往往比 BSD 更健壮。

标签: shell character-encoding sed


【解决方案1】:

如果您的字符集是单字节编码(如 ISO-8859-n 系列)或 UTF-8,其中换行符与 ASCII 中的相同,并且不会出现 NUL 字符 (\0) ,您的操作很可能有效。如果文件使用 UTF-16,则不会(因为 NUL)。为什么它应该适用于 ASCII 字符串的简单搜索和替换:我们假设,您的编码是 ASCII 的超集,对于这样的简单匹配,sed 将主要在字节级别上工作,只需将一个字节序列替换为另一个.

但是:对于更复杂的操作,例如当您的替换或替换字符串包含特殊字符时,您的结果可能会有所不同。例如,如果控制台编码/区域设置与文件编码不同,您在命令行中输入的重音字符可能不适合文件中的编码。可以解决这个问题,但需要小心。

sed 中的某些操作取决于您的语言环境,例如哪些字符被视为字母数字。例如,比较在波兰语 UTF-8 语言环境和使用 ASCII 的 C 语言环境中执行的以下替换:

$ echo "gęś gęgała" | LC_ALL=pl_PL.UTF-8 sed -e 's/[[:alnum:]]/X/g'
XXX XXXXXX
$ echo "gęś gęgała" | LC_ALL=C sed -e 's/[[:alnum:]]/X/g'
Xęś XęXXłX

但如果你只想替换文字字符串,它会按预期工作:

$ echo "gęś gęgała" | LC_ALL=pl_PL.UTF-8 sed -e 's/g/G/g'
Gęś GęGała
$ echo "gęś gęgała" | LC_ALL=C sed -e 's/g/G/g'
Gęś GęGała

如您所见,结果不同,因为重音字符的处理方式因地区而异。简而言之:文字 ASCII 字符串的替换很可能可以正常工作,需要研究更复杂的操作,并且可能工作或不工作。

【讨论】:

  • +100 感谢您为帮助陌生人所做的有益解释和努力。所以看起来改变环境语言/字符集以匹配每个目标文件会有所帮助。 ### 此外,我的搜索/替换仅针对仅包含 ASCII 字符的行中的 ASCII 字符 - 如果字符集可能会混淆换行符,我是否正确理解带有其他字符的行应该造成潜在问题?
  • @user1264579 是的。如果您只用其他文字字符串替换文字字符串,那么换行符与 ASCII 和 NUL 中的相同就足够了,不会出现替换工作。 ASCII 以外的字符应该没问题。当然,即使替换是按字节正确的,您也需要确保它的含义与您希望它在目标编码中的含义相同。如果您在使用 Latin-2 的文件中正确替换编码为 UTF-8 的 ę,则替换将正确插入 UTF-8 中代表 ę 的 2 个字节,但这些字节在以拉丁语显示时将显示为垃圾-2 与文件的其余部分。
猜你喜欢
  • 2011-08-27
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 2014-02-07
  • 2022-10-07
  • 2021-07-28
  • 1970-01-01
  • 2015-01-16
相关资源
最近更新 更多