使用 find 或 grep 查找来自不同编码系统(Windows 到 Linux)的带有重音字符的文件名

2023-12-25

我试图迟到标记一个与我类似的问题(在 Linux 文件系统上查找非 UTF8 文件名 https://stackoverflow.com/q/623764/522104)以获得进一步的答复,到目前为止还没有运气,所以这里又来了......

我和上面链接中的OP有同样的问题,convmv是一个修复自己的文件系统的好工具。因此,我的问题是学术性的,但我发现“find”无法找到非标准 ascii 字符这一点令人不满意(事实上我无法相信)。

有没有人知道使用什么选项组合来查找似乎是 unicode FS 上包含非标准字符的文件名,在我的例子中,字符似乎是 8 位扩展 ascii 而不是 unicode,这些文件来自Windows 机器(iso-8859-1),我经常需要获取它们。我很想看看 find 和/或 grep 如何做与 convmv 相同的事情。

示例文件:

> ls
Abc�def ÉÈéèáà-rest everest éverest

> ls -b
Abc\251def  ÉÈéèáà-rest  everest  éverest

第一个文件来自Windows(或用touch $(printf "Abc\xA9def")).

> find . -regex '.*[^a-zA-Z./].*'
./ÉÈéèáà-rest

> ls | egrep '[^a-zA-Z]'
ÉÈéèáà-rest

几乎丢失了所有这些(连字符保存了该文件,可以使用彩色 grep 看到)。这里发生的事情都不是我所期望的:find 和 grep 都无法将重音字母视为超出提供的范围 [^a-zA-Z./]。

> find . -regex '.*é.*'
./éverest
./ÉÈéèáà-rest

> ls | egrep 'é'
ÉÈéèáà-rest
éverest

> ls | egrep '[é]'
ÉÈéèáà-rest
éverest

> find . -regex '.*[é].*'
./éverest
./ÉÈéèáà-rest

奇怪的是,当提供时(包括在范围内),两者都能够拾取标准口音。任何使用 \xA9、\0251 或 \o251 的 find 或 grep 尝试都会失败(不匹配)。

> ls | fgrep e
Abc�def
ÉÈéèáà-rest
everest
éverest

寻找无争议的字符会显示所有带有 grep 的文件,正如我所期望的那样。

> find . -regex '.*e.*'
./éverest
./ÉÈéèáà-rest
./everest

> find . -name '*e*'
./éverest
./ÉÈéèáà-rest
./everest

然而, find 是非常具有歧视性的:即使查找正常字符,在我看来,它也会消除包含超出文件系统名称编码模式可接受字符范围的字符的文件名。

就我而言,如果该文件位于文件系统中,那么 find 应该找到它,对吧?但也许有一个我不知道的功能?

任何见解将非常感激。


Jander 回答了我在超级用户上发布的同一问题 https://superuser.com/questions/218825/using-find-or-grep-to-locate-filenames-with-accented-characters-from-a-different/218831#218831

詹德的回答完美地完成了这项工作,对于那些有兴趣从中获得更多信息的人,这里还有一个提示。

当 LANG=C 时,find 显示带问号的非 ascii 字符。要将其转换回该文件系统的正常显示,只需将输出通过管道传输到 cat.

LANG=C find . -regex '.*[^a-zA-Z./-].*'
./??verest
./????????????-rest
./Abc?def

LANG=C find . -regex '.*[^a-zA-Z./-].*' | cat
./éverest
./ÉÈéèáà-rest
./Abc�def
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 find 或 grep 查找来自不同编码系统(Windows 到 Linux)的带有重音字符的文件名 的相关文章

随机推荐