LC_ALL=C 是否应该始终用于非区域设置特定的 sed 操作?

Should LC_ALL=C Always be used for Non-Locale-Specific sed Operations?

我有 JSON 个文件,这些文件带有我在使用 jq 进行操作之前删除的注释。我刚刚遇到了一个有趣的问题,我收到了一个 JSON 文件,其中包含一些富文本引号字符(十六进制 93 和十六进制 94)的注释注释。我现有的 sed 点 . 字符与这些字符不匹配。这是一个演示:

首先输入:

% echo -e '# \x93text\x94\n{"a":1}' | od -c
0000000   #     223   t   e   x   t 224  \n   {   "   a   "   :   1   }
0000020  \n
0000021
%

这是转换:

% echo -e '# \x93text\x94\n{"a":1}' | sed 's/^\s*#.*//' | od -c
0000000 223   t   e   x   t 224  \n   {   "   a   "   :   1   }  \n
0000017
%

请注意,sed 表达式中的点字符与十六进制 93 字符不匹配。但是,如果我包括 LC_ALL=C:

% echo -e '# \x93text\x94\n{"a":1}' | LC_ALL=C sed 's/^\s*#.*//' | od -c
0000000  \n   {   "   a   "   :   1   }  \n
0000011
%

然后 sed 表达式中的点字符匹配十六进制 93 和十六进制 94 字符。 sed 文档部分 Locale Considerations 谈到括号表达式,但上面的行为似乎证明这个问题发生在其他地方。

有趣的是,删除而不是替换并没有显示这个问题:

% echo -e '# \x93text\x94\n{"a":1}' | sed '/^\s*#.*/d' | od -c         
0000000   {   "   a   "   :   1   }  \n
0000010

鉴于我操作的是带注释的 JSON 文件,我认为在 sed 语句中添加 LC_ALL=C 的解决方案是合理的。

所以,我的问题是: 正在使用 LC_ALL=C 我在进行非语言环境特定的 sed 转换时一直想使用的东西(就像适用于带注释的 JSON 文件)?如果没有,有什么替代方法可以避免我上面显示的问题?

我的环境:

C 语言环境是一种特殊的语言环境,旨在成为最简单的语言环境。您也可以说,虽然其他语言环境适用于人类,但 C 语言环境适用于计算机。 在 C 语言环境中,字符是单字节,字符集是 ASCII

在某些系统上,POSIX 语言环境存在差异,例如 non-ASCII 个字符的排序顺序未定义。

所以 LC_ALL=C 是将非第 8 位字符考虑在内的安全方法。

查看比较

使用 LC,sed 算作字符的一部分

echo -e '# \x93text\x94\n{"a":1}' | LC_ALL=C sed 's/[^[:alnum:]]/[HERE:&] /g' | od -c
0000000   [   H   E   R   E   :   #   ]       [   H   E   R   E   :
0000020   ]       [   H   E   R   E   : 223   ]       t   e   x   t   [
0000040   H   E   R   E   : 224   ]      \n   [   H   E   R   E   :   {
0000060   ]       [   H   E   R   E   :   "   ]       a   [   H   E   R
0000100   E   :   "   ]       [   H   E   R   E   :   :   ]       1   [
0000120   H   E   R   E   :   }   ]      \n

没有 LC,sed 不计入要考虑的字符的一部分([[:alnum:]][^[:alnum:]] 不要 参见 第 8 位字符)

 echo -e '# \x93text\x94\n{"a":1}' | sed 's/[[:alnum:]]/[HERE:&] /g' | od -c
0000000   #     223   [   H   E   R   E   :   t   ]       [   H   E   R
0000020   E   :   e   ]       [   H   E   R   E   :   x   ]       [   H
0000040   E   R   E   :   t   ]     224  \n   {   "   [   H   E   R   E
0000060   :   a   ]       "   :   [   H   E   R   E   :   1   ]       }
0000100  \n

echo -e '# \x93text\x94\n{"a":1}' | sed 's/[^[:alnum:]]/[HERE:&] /g' | od -c
0000000   [   H   E   R   E   :   #   ]       [   H   E   R   E   :
0000020   ]     223   t   e   x   t 224  \n   [   H   E   R   E   :   {
0000040   ]       [   H   E   R   E   :   "   ]       a   [   H   E   R
0000060   E   :   "   ]       [   H   E   R   E   :   :   ]       1   [
0000100   H   E   R   E   :   }   ]      \n