列出名称中带有问号(?)的所有文件和文件夹

列出名称中带有问号(?)的所有文件和文件夹

当我将大量文件和文件夹从 Windows 系统复制到 Linux 系统时遇到了编码问题,现在我可以看到许多文件名称中带有问号。

我想知道有多少文件/文件夹受到影响,所以我尝试

find . -type d -o -type f -name '*\?*'

find . -type d -o -type f -name '*?*'

没有运气。

它列出了许多名称中没有问号的文件/文件夹...(请注意,搜索必须是递归的)

你有解决方案吗 ?

(此外,如果您有第二个命令来计算受影响的文件数量,我会很高兴:))

[编辑] 感谢您的回答,但问题似乎实际上是find由于编码问题,这些文件和文件夹被排除在命令之外。首先,它似乎不是 ? 字符,而是更像 � 之类的东西。我尝试搜索它们名称的其他部分,但它们仍然没有出现(如果我重命名它们,我就可以摆脱编码问题,它们会再次可见find)。
帮我列出并统计它们。

谢谢

答案1

您有一个需要解决的编码问题。

显示?ls是一个占位符,并不代表该文件名为?

这是重现问题的方法,使用iconv在通常的 utf8 配置的 Linux 系统上:

$ mkdir /tmp/test
$ cd /tmp/test
$ touch $(echo é | iconv -t windows-1252) # that's the eacute character
$ ls
?
$ ls|cat

最后一行只是表示“显示了无效的 utf8 编码”,可能无法正确复制/粘贴而不会丢失其信息。windows-1252只是一个例子。 可能还有许多其他的(例如iso-8859-1:)。 信息仍然存在:

$ ls|iconv -f windows-1252
é

因此,一旦您弄清楚在 Linux 上用哪种编码来编写这些文件(尝试iconv -l|egrep -i 'win|iso-8859'可能的候选列表),您就可以尝试批量重命名。请注意,虽然一个示例可能有效,但它可能会在其他文件上失败。

重命名示例:

ENCODING="windows-1252" # once the right encoding was found
for file in *; do
    dest="$(printf '%s' "$file" | iconv -f "$ENCODING")"
    mv -i "$file" "$dest.new"
    mv -i "$dest.new" "$dest"
done

答案2

find意思-o是“或者“,所以您可能遇到了优先级问题……

你指的是哪一个?

  • -type d 或者-type f -name '*\?*'
    • 所有目录
    • 所有文件?名称中包含
  • -type d 或者 -type f -name '*\?*'
    • ?仅限名称中含有 的目录和文件

您可以使用大括号find,因此您的命令变成:

find . \( -type d -o -type f \) -name '*\?*'

例子:

$ touch 'aaa' 'a?a'
$ mkdir 'bbb' 'b?b'
$ touch 'bbb/ccc' 'bbb/c?c'
$ find . -type d -o -type f -name '*\?*'
.
./bbb
./bbb/c?c
./b?b
./a?a
$ find . \( -type d -o -type f \) -name '*\?*'
./bbb/c?c
./b?b
./a?a

然后,您可以通过管道将输出输入到以下行中wc -l来计算行数:

$ find . \( -type d -o -type f \) -name '*\?*' | wc -l
3

其他人建议您删除-type d -o -type f。这是一个不错的选择,除非您尝试排除其他类型(例如:块设备/字符设备/符号链接/管道/套接字)

答案3

您的第一个命令可以修改如下:

find . -type d  -name '*\?*' -o -type f -name '*\?*'

这样,过滤器就适用于文件和目录(否则您将列出所有目录和仅过滤文件)。


简单得多,正如建议的那样吉米在评论中,将是:

find . -name '*\?*'

请注意,find默认在当前目录中搜索,因此.也可以省略:

find -name '*\?*'

另外,你可以 grep 结果:

find | grep ?

计算相关实体(建议的解决方案是吉米):

find | grep ? | wc -l

命令来计算受影响的文件数量

正如您所问的,只计算文件数量:

find -type f | grep ? | wc -l

测试运行:

?aa
a?a
aa?
aaa
$ find | grep ?
./a?a
./?aa
./aa?

评论:

我认为grep需要-F按字面意思处理的选项?,但看来它无论如何都不会被视为特殊字符,除非-E使用开关。

   -F, --fixed-strings
          Interpret PATTERN as a list of fixed strings (instead of regular expressions), separated by newlines, any of which is to be matched.

   -E, --extended-regexp
          Interpret PATTERN as an extended regular expression (ERE, see below).

问题已更新:

列出名称中带有问号 (�) 的所有文件和文件夹

没有太大变化:find -name '*�*'要么find | grep �

测试运行:

�aa
a�a
aa�
aaa
$ find -name '*�*'
./a�a
./�aa
./aa�

还有一个问题:

如果要查找包含外来字符的文件或目录,可以通过指定要查找的字符来过滤结果预计. 只需将您喜欢的任何字符添加到列表中想要强调的是:

find | grep -P '[^\w./-_*]'

这在你不知道这是有问题的字符。请注意,这个问题在 Stackexchange 上已经被问过多次,并且已经得到过回答。

相关内容