【发布时间】:2017-07-01 09:01:17
【问题描述】:
我有带有 cmets 注释的 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 的解决方案是合理的。
所以,我的问题是:在进行非语言环境特定的 sed 转换时,我是否一直想使用 LC_ALL=C (适用于带注释的 JSON 文件)?如果没有,有哪些替代方法可以避免我上面显示的问题?
我的环境:
- CentOS 7.3 [kernel-3.10.0-514.6.1.el7.x86_64]
- sed (GNU sed) 4.2.2 [sed-4.2.2-5.el7.x86_64]
- Bash 4.2.46(1) [bash-4.2.46-21.el7_3.x86_64]
【问题讨论】:
-
不是 KSH 下的问题(环境肯定不同),但尝试你的线路我得到这个可以帮助
echo -e '# \x93text\x94\n{"a":1}' | sed '/^[[:space:]]*#.*/ s//[HERE]/' | od -c给0000000 [ H E R E ] 223 t e x t 224 \n { " a 0000020 " : 1 } \n所以 sed 估计替换到行尾,而不是选择 -
@NeronLeVelu 是的,无论如何这都是非常奇怪的行为。由于 sed 网页建议包含
LC_ALL=C,这让我想知道这是否是 sed 中错误的解决方法,或者它是否是一个难以理解的功能。