是否有Linux函数可以检查是否存在大小写不同的文件名?

mwkjh3gx  于 2023-03-01  发布在  Linux
关注(0)|答案(2)|浏览(266)

**是否有Linux函数可用于检查是否存在大小写不同的文件名?**例如,查找Hello.txt和hello.txt之间的差异

例如,如果我想打开Hello.txt,我会这样做:

  • 尝试打开文件(尝试 Hello.txt

如果失败:

  • 检查文件夹中是否有大小写不同的文件(查找文件 hello.txt
5f0d552i

5f0d552i1#

不,没有。你需要遍历目录中的文件,然后手动检查。不过有一些函数可以帮助你,例如scandir。从C++17开始,你有std::filesystem::directory_iterator来遍历目录,如果需要的话,标准库中的泛型算法可以帮助你实现。
另外,一些文件系统是不区分大小写的,无论如何都会考虑这两个等价的文件名。但是通常Linux认为文件名只是一个字节值序列。所以如果文件名中有非ASCII值,你还需要决定用什么编码来解释文件名。如果你采用Unicode编码,弄清楚“不同的大小写”的确切含义也不是件小事。

vh0rcniy

vh0rcniy2#

如果存在这样的函数,将有2n个组合要检查,其中n是文件名的长度。
对于hello.txt,如果包括扩展,将有256种检查方式(28 = 256),与指数时间复杂度一样,随着n的增长,它将很快成为一个无法管理的问题。
这是非常低效的,所以进行大小写不敏感的文件名匹配的最好方法是将所有内容转换为小写(或大写),然后像@mark-setchell指出的那样进行比较。
因为你标记了c和linux,我已经包含了一个在linux上工作的解决方案,用c写的,记住strcasecmp函数只存在于linux系统上。
同样,如果我们跟踪匹配的索引,如果我们需要准确的区分大小写的文件名,我们就不需要经历2n次迭代。

#include <iostream>
#include <filesystem>
#include <vector>
#include <cstring>
#include <algorithm>

int main() {
  std::string path = "./";
  std::string to_find = "hello.txt";
  bool exists = false;
  int found_index = 0;
  std::vector<std::string> arr;
  for (const auto &entry: std::filesystem::directory_iterator(path)) {
    arr.push_back(entry.path());
  }
  std::sort(arr.begin(), arr.end()); //std::filesytem::directory_iterator's 
                                //order cannot be determined, so the
                                //vector is sorted. This step is optional though
  for (int i=0; i<arr.size(); i++) {
    std::string a = arr[i].substr(path.size()); // Remove prefix path
    if (strcasecmp(a.c_str(), to_find.c_str()) == 0) {
      exists = true;
      found_index = i;
      break;
    }
  } 
  if (exists) {
    std::cout << "File found and the exact file name is \"" << arr[found_index] << "\"" << std::endl;
  } else {
    std::cout << "File not found" << std::endl;
  }
}

如果找到匹配项,上面的程序也会打印出确切的文件名。

相关问题