使用sed如何移除非ASCII字符

10

我希望能够从某个文件中删除非ASCII字符。我已经尝试了许多正则表达式。

sed -e 's/[\d00-\d128]//g'  # not working

cat /bin/mkdir | sed -e 's/[\x00-\x7F]//g' >/tmp/aa

但是这个文件包含一些非ASCII字符。

[root@asssdsada ~]$ hexdump /tmp/aa |more
          00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF

00000000  45 4C 46 B0 F0 73 38 C0 - C0 BC BC FF FF 61 61 61  ELF..s8......aaa
00000010  A0 A0 50 E5 74 64 50 57 - 50 57 50 57 D4 D4 51 E5  ..P.tdPWPWPW..Q.
00000020  74 64 6C 69 62 36 34 6C - 64 6C 69 6E 75 78 78 38  tdlib64ldlinuxx8
00000030  36 36 34 73 6F 32 47 4E - 55 42 C8 C0 80 70 69 42  664so2GNUB...piB
00000040  44 47 BA E3 92 43 45 D5 - EC 46 E4 DE D8 71 58 B9  DG...CE..F...qX.
00000050  8D F1 EA D3 EF 4B 86 FC - A9 DA 79 ED 63 B5 51 92  .....K....y.c.Q.
00000060  BA 6C FC D1 69 78 30 ED - 74 F1 73 95 CC 85 D2 46  .l..ix0.t.s....F
00000070  A5 B4 6C 67 DA 4A E9 9A - 4B 58 77 A4 37 80 C0 4F  ..lg.J..KXw.7..O
00000080  F3 E9 B2 77 65 97 74 F9 - A2 C0 F2 CC 4A 9C 58 A1  ...we.t.....J.X.
5个回答

21
这似乎不能在 sed 中使用。也许可以用 tr
tr -d '\200-\377'

或者使用补码:

tr -cd '\000-\177'

@EladTabak:它应该可以工作。你能举个例子说明它不起作用的情况吗? - Thor
在macOS High Sierra上,我收到了这个错误:“tr:非法字节序列”。 - codeforester
1
@codeforester:我使用GNU coreutils中的tr进行了测试。 - Thor
1
tr -cd '\001-\177' 可以去除 NULL 字符,这样做是值得的,因为许多工具(如 grep)会将包含 null 的输入识别为二进制。二进制文件(标准输入)匹配。 - ericcurtin

8
你是否尝试过?
cat /bin/mkdir | tr -cd "[:print:]"

我认为它解决了问题吗?
如果只有文本内容能够吸引您,您也可以使用。
cat /bin/mkdir | strings

3

您知道这个文件当前使用的编码方式吗?如果知道,您可以使用iconv进行转换。它是一种从一种字符编码转换为另一种字符编码的工具。所以,如果原始文件是UTF-8,并且想要转换为ASCII,可以使用以下命令:

iconv -f utf8 -t ascii <inputfile>

输入文件上的file命令可能会告诉您当前的编码格式。

有趣的是,有一个名为enca 的命令,如果您知道文件内容的语言,它将尽力确定正在使用的字符编码。

这个其他问题可能就是答案。


我正在使用Linux系统工作,该系统的命令池非常有限,而且没有“iconv”命令。 - user87005
从hexdump的输出来看,这是一个二进制文件吗?(从开头的ELF猜测)如果是,去除非ASCII字符的目的是什么?这将导致二进制文件损坏。 - chooban
这只是一个例子,朋友。 - user87005
1
同样的命令在Perl中可以正常工作,但我需要用sed。 cat /bin/mkdir | perl -ne 's/[^[:ascii:]]//g;print $_;' - user87005
在我的电脑上也找不到enca。%enca enca:命令未找到。 - user87005
显示剩余2条评论

1
这里提供的解决方案对我没有用。也许我的问题不同,但我需要从原本纯ASCII文本中去除ASCII颜色和其他字符。
然而,以下方法对我有效:
从ASCII文本中去除转义码
sed -E 's/\x1b\[[0-9]*;?[0-9]+m//g'

在上下文中(BASH):

$ printf "\e[32;1mhello\e[0m\n"
hello

$ printf "\e[32;1mhello\e[0m\n" | cat -vet
^[[32;1mhello^[[0m$

$ printf "\e[32;1mhello\e[0m\n" | sed -E 's/\x1b\[[0-9]*;?[0-9]+m//g' | cat -vet
hello$

0

尝试使用 sed -i 选项,例如:

sed -i 's/[\d128-\d255]//g' MYFILE.txt

它将在文件中替换所有非ASCII字符。


至少对我来说——在我的文件上运行此操作会删除所有小写ASCII字符。 - Uncle Iroh

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