目的:
tr -cd '\12\40-\176'
但带有重音符号,例如:á, í, ű, ő, ö, ü, ű, ú, ó, é。
以八进制表示:
"á" is 341
"\n" is 12
所以我尝试:
[user@notebook ~]$ printf 'XXXá\nXXX' | tr -cd '\12\341' | cat -vte -
$
[user@notebook ~]$
问题:为什么 tr 在输出中不留下“á”?也许它不知道扩展 ASCII 表字符或者什么?
更新:
[user@notebook small]$ printf 'árvíztűrő tükörf\túrógép\n' | strings -eS -n1
árvíztűrő tükörf úrógép
[user@notebook small]$
不需要该选项卡,但字符串将其保留在其中。
更新#2:
[user@notebook ~]$ locale -a | grep hu_HU.utf8
hu_HU.utf8
[user@notebook ~]$ printf 'someárvíztűrő tükörf\túrógép\ntext' | LANG=hu_HU.utf8 sed 's/[\d128-\d255]//g;s/[\d000-\d031]//g' | cat -vte -
sed: -e expression #1, char 19: Invalid collation character
[user@notebook ~]$
答案1
“á”是 341
不,不是。您的字符集是 UTF-8,其中 á 是字符 U+00E1,它被编码为两字节序列\xc3\xa1
= \303\241
。当您写入\341
的参数时tr
,它会被解释为 byte \341
。
它不知道扩展 ASCII 表字符
是的,确实如此——只不过不存在“扩展 ASCII 表字符”这样的东西:ASCII 是一个 7 位字符集。您指的是扩展 ASCII 的字符集,并且tr
确实支持它们。tr
根据当前区域设置处理字符或字节。
tr -cd '\12\40-\176'
ASCII 中的意思是保留可打印字符和换行符。在任何语言环境中,您都可以将“可打印字符”说成[:print:]
。\n
是表示换行符的更清晰的方式。因此:
tr -cd '\n[:print:]'
不幸的是,某些实现tr
(包括 GNU 版本)无法处理 UTF-8 中的字符集。您可以使用 sed 代替。
sed 's/[^[:print:]]//g'
答案2
使用strings
例如
$ printf 'XXXhelloá\nYYY' | strings -es -n1
XXXhello
YYY
strings 有各种选项(man strings
了解详细信息)用于从输入字符串或文件中提取文本(包括 -es,仅 7 位字符)。
如果你想排除更多“特殊”字符,你可以使用 sed:
# printf 'someárvíztűrő tükörf\túrógép\ntext' | LANG=C sed 's/[\d128-\d255]//g;s/[\d000-\d031]//g' | cat -vte -
somervztr tkrfrgp$
text$
如果您想将文本组合在一行上,只需通过 xargs 管道传输文本,这会用空格替换任何换行符:
$ printf 'someárvíztűrő tükörf\túrógép\ntext' | xargs | LANG=C sed 's/[\d128-\d255]//g;s/[\d000-\d031]//g;s/\n//g' | cat -vte -
somervztr tkrf rgp text$