【发布时间】:2022-01-06 04:06:24
【问题描述】:
目前,我正在处理一堆旧文件,这些文件在它们的生命周期中已经看到了很多机器、操作系统和文件系统。其中一些包含德语变音符号(ä、ö、ü),显然这些已导致某些文件名在其中一个移动过程中中断。一个原名为
的文件München.txt
显示为
M?nchen.txt (invalid encoding)
在当前托管它们的 ubuntu 系统上。
所以现在我正在尝试批量修复它们。在循环浏览带有初稿的文件时,我偶然发现了这种现象:
-
在屏幕上回显给我带有问号的文件名,我理解这是对文件名中非法字符的解释:
./list_files.sh path_to_files M?nchen.txt K?ln.txt -
如果我将输出保存到文件中,它会给我一个仍然包含无效字符的二进制文件:
./list_files.sh path_to_files > file_list less file_list M<FC>nchen.txt K<F6>ln.txt
这是代码:
#!/bin/bash
rootdir=$1
find "$rootdir" -print0 | while IFS= read -r -d '' broken_file_name; do
echo $broken_file_name
done
我正在努力理解:
- 为什么屏幕输出与文件中的不同?字符替换发生在哪里,问号是在哪里创建的?
- 如何防止在脚本进程中使用问号的东西解释非法字符?它可以防止我有选择地用相应的正确字符替换非法字符。
【问题讨论】:
-
less的不同行为可能是less的事情。来自手册:“否则,字符在尖括号中显示为十六进制数字。可以通过设置 LESSBINFMT 环境变量来更改此格式。”(Otherwise 是对于不是控制字符的二进制字符)。而echo、printf、cat... 不可打印的字符显示为?。 -
./list_files.sh path_to_files | cat的问号还在吗?如果是这样,它们可能会被终端打印为无法识别的字节。如果 not,我猜想iconv正在被使用,但前提是 stdout 是终端(它打印?以表示无法识别)。字节\xFC和\xF6不是有效的 ASCII 或 UTF-8,因为它们在 128-255 之间(以 10 为基数)。less像<F6>一样打印二进制字节\xF6。您可以使用hexdump(或hd)以获得更清晰的视图。另请查看iconv及其//TRANSLIT标志,以帮助转换。
标签: bash ubuntu character-encoding