用空格替换所有的圆点符号

4
如何用空格代替子弹符号(八进制值:225,十六进制值:95)?
我尝试了以下命令:

echo '•test' | tr '\225' ' '

echo '•test' | awk '{gsub(/\225/," ");print $0}'

echo '•test' | sed 's/\o225/ /g'

echo '•test' | LANG='' sed 's/\o225/ /g'

echo '•test' | sed 's/\x95/ /g'

上述命令不起作用。
2个回答

7
让我们看一下为什么你目前的努力失败了:
$ echo '•test' | hexdump -C
00000000  e2 80 a2 74 65 73 74 0a                           |...test.|
00000008

这些小圆点实际上是三个字节——e2 80 a2,而不是一个单独的0x95
纠正后的sed表达式可以正常工作:
echo '•test' | sed -e 's/•/ /g'

...或者(使用在/bin/sh中不可用的bash扩展语法)...

echo '•test' | sed -e  $'s@\xe2\x80\xa2@ @g'

... 或者(使用bash内置替换功能):

s='•test'             # original string in s
orig='•'              # item to replace
new=' '               # thing to replace it with
s2=${s//"$orig"/$new} # result in s2

...或者(使用GNU sed扩展,按照@anubhava的说法)...

echo '•test' | sed 's@\xe2\x80\xa2@ @g'

为什么要使用“@”符号?我用以下命令进行了测试:echo '•test' | sed 's/\xe2\x80\xa2/ /g'。它有效地运行了。 - user2874781
1
@user2874781,我习惯使用@作为标记符号,因为在需要替换的内容中经常出现/,所以选择它作为标记符号并不是一个好的选择。在这种情况下,两者都不存在,所以无论哪种方式都没有什么特别的区别。(在许多情况下,需要选择一个不能在数据内部的标记符号,这使得sed成为一种很差的工具选择)。 - Charles Duffy
1
@SylvainLeroux,我冒险相信StackOverflow原样复制他们的原始内容,并查看了他们复制并粘贴的内容。 - Charles Duffy
1
@anubhava:并非所有的 sed 实现都支持 \xnn 转义 - 例如,GNU sed 可以使用,但 BSD/OSX 的 sed 不行。根据 POSIX 标准,sed 仅支持 基本 正则表达式,其中序列 \x未定义 的 - 请参见 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_03 - mklement0
@SylvainLeroux:当然,但这已经是这个答案的一部分了(并且伴随着已经提到的警告,它是一个bash[/ksh/zsh]主义)。 - mklement0
显示剩余4条评论

3
作为 Charles Duffy 出色答案的补充,与字符“bullet”对应的“bytes”取决于所使用的文件编码。
例如,“bullet”为:
- 如果文件编码为(Windows)CP1252,则为单个字节0x95。 - 如果文件编码为(传统的)Macintosh Roman编码,则为单个字节0xa5。 - 如果文件编码为UTF-8,则为三个字节序列。
对于“单字节编码”,tr 是一个很好的选择。就我而言,我更喜欢略微不同的语法,但那也应该可以运行。
sh$ tr $'\x95' ' ' < cp1252.txt 
 test

sh$ tr $'\xa5' ' ' < mac.txt 
 test

如果您的文件是UTF-8编码...那么您已经得到了答案!

+1:我没有查找0x95假设来自哪个编码,但这是有用的背景信息。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接