如何只在文件中保留给定的字符?

如何只在文件中保留给定的字符?

目的:

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$

相关内容