查找某个目录下的所有文件(包括子目录)

该博客展示了一段C语言代码,用于在指定目录(这里是C盘)下查找文件。代码通过递归的方式遍历目录,输出文件路径。原代码经作者稍作修改和整理后进行了测试。

//原作者不详,偶然发现。然后稍做了修改,测试了以下。整理了一下。

#include "stdio.h"
#include "windows.h"
#include "winbase.h"
void FindFileInDir(char* rootDir);

main()
{
 FindFileInDir("C://");
}

void FindFileInDir(char* rootDir)//, char* strRet)
{
    char fname[1024];
    ZeroMemory(fname, 1024);
    WIN32_FIND_DATA fd;
    ZeroMemory(&fd, sizeof(WIN32_FIND_DATA));
    HANDLE hSearch;
    char filePathName[256];
    char tmpPath[256];
    ZeroMemory(filePathName, 256);
    ZeroMemory(tmpPath, 256);
    strcpy(filePathName, rootDir);
    BOOL bSearchFinished = FALSE;
    if( filePathName[strlen(filePathName) -1] != '//' )
    {
       strcat(filePathName, "//");
    }
    strcat(filePathName, "*");

    hSearch = FindFirstFile(filePathName, &fd);
 
    //Is directory

    if( (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

       && strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )      
    {

       strcpy(tmpPath, rootDir);


       strcat(tmpPath, fd.cFileName);

    if( tmpPath[strlen(tmpPath) -1] != '//' )
  {
   strcat(tmpPath, "//");
  } 
       FindFileInDir(tmpPath);
    }
    while( !bSearchFinished )
    {

       if( FindNextFile(hSearch, &fd) )
       {

           if( (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

              && strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )      
           {

              strcpy(tmpPath, rootDir);

              strcat(tmpPath, fd.cFileName);
      if( tmpPath[strlen(tmpPath) -1] != '//' )
    {
     strcat(tmpPath, "//");
    } 

              FindFileInDir(tmpPath);
           }
           else   if( strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..") )
                  {
      printf("%s%s/n",rootDir,fd.cFileName);
         
                  }
       }
       else
    {
           if( GetLastError() == ERROR_NO_MORE_FILES )        
           {
              bSearchFinished = TRUE;

           }
           else
              bSearchFinished = TRUE;
       }
    }
    FindClose(hSearch);

}

<think> 我们正在解决一个问题:在shell中查找某个目录下所有子目录中包含'.so'的文件(即共享库文件)的方法。 根据用户上一次的问题,他提到了“查找指定目录下所有子目录中包含.so的文件”,而之前的引用中提到了使用find命令的方法。 引用[1]中给出的方法是:使用find命令查找特定目录下的所有.so文件。 示例代码:sos=$(find "$SRC_DIR" -name *.so) 但是,用户的问题中要求的是“包含'.so'的文件”,这里有两种理解: 1. 文件名中包含字符串“.so”的文件(不一定以.so结尾) 2. 文件扩展名为.so的文件(即以.so结尾) 根据引用[1]中的例子,它是以.so结尾,即扩展名为.so。 然而,用户的问题描述是“包含'.so'的文件”,所以我们应该同时考虑两种情况吗? 但是,通常我们所说的.so文件是指共享库文件,它们通常以“.so”作为后缀,但也有可能后面还有版本号,例如:libfoo.so.1.2.3。 因此,更准确的做法是查找文件名中包含“.so”的文件,而不仅仅是后缀为.so。因为版本号也是包含在文件名中的。 另外,注意引用[4]中使用了grep命令来查找文件内容中包含特定字符串的文件,但用户的问题是要找文件名中包含“.so”的文件,而不是文件内容。 所以,我们这里使用find命令来查找文件名中包含“.so”的文件方法一:查找文件名中包含“.so”的文件 命令:find 目标目录 -type f -name "*.so*" 解释: - `-type f`:只查找普通文件(排除目录等) - `-name "*.so*"`:匹配所有文件名中包含“.so”的文件(注意:这里的模式匹配是通配符匹配,不是正则表达式) 但是,这样可能会匹配到一些不是共享库的文件,比如文件名中有“.so”的其他文件。不过,通常共享库文件都是以“.so”为后缀或包含“.so”和版本号。 方法二:如果只想找以.so结尾的文件(不包含版本号),则使用: find 目标目录 -type f -name "*.so" 方法三:如果希望匹配以.so开头或者包含.so的文件,且为了避免匹配到中间含有.so的任意文件(比如myfile.so.txt),我们可以使用更精确的正则表达式。 但是,find命令的-name选不支持正则表达式,我们可以使用-regex选。 例如,匹配以.so或者.so.后面跟数字的文件(常见的共享库命名规则): find 目标目录 -type f -regex ".*\.so\(\.[0-9]+\)*" 不过,用户的问题并没有要求这么严格,通常我们只需要查找文件名中带有“.so”的文件即可。 考虑到简单性和通用性,我们推荐使用第一种方法。 因此,在shell中查找指定目录下所有子目录文件名包含'.so'的文件,可以使用: ```bash find /path/to/directory -type f -name "*.so*" ``` 注意:如果目录路径包含空格,最好用双引号括起来。 另外,如果要将结果保存到变量中,可以: ```bash so_files=$(find "/path/to/directory" -type f -name "*.so*") ``` 然后可以遍历这个变量(注意:如果文件名包含空格,这种方法会有问题,更好的做法是使用数组或while循环)。 为了避免文件名中的空格等问题,我们可以使用数组(在bash中): ```bash mapfile -t so_files < <(find "/path/to/directory" -type f -name "*.so*") ``` 然后可以遍历数组: ```bash for file in "${so_files[@]}"; do echo "$file" done ``` 或者直接使用find的-exec选处理每个文件。 根据引用[1]中的例子,用户可能只需要简单的变量存储,所以我们也可以直接使用命令替换,但要注意如果文件太多可能会超出命令行的最大长度。 因此,我们给出两种方案: 方案1:直接输出到屏幕 ```bash find "/path/to/directory" -type f -name "*.so*" ``` 方案2:存储到数组(推荐在脚本中使用) ```bash # 在bash中 declare -a so_files while IFS= read -r -d $'\0' file; do so_files+=("$file") done < <(find "/path/to/directory" -type f -name "*.so*" -print0) ``` 注意:这里使用了-print0和read -d $'\0'来处理文件名中的空格和换行等特殊字符,这是最安全的方式。 但是,如果系统不支持-print0(如一些传统的Unix),则可以使用简单的循环,但要注意文件名中的空格。 在OpenWrt系统中,通常使用busybox的find,它支持-print0(因为OpenWrt的busybox一般配置了该选)。 因此,我们给出一个兼容性较好的方法: 如果不需要处理特殊字符,可以直接使用: ```bash find "/path/to/directory" -type f -name "*.so*" ``` 如果需要处理特殊字符,使用: ```bash find "/path/to/directory" -type f -name "*.so*" -print0 | xargs -0 ls -l ``` 或者使用循环读取。 总结:根据需求选择合适的方法。 现在,我们按照用户要求,回答如何在shell中查找指定目录下所有子目录中的包含'.so'的文件(这里指文件名包含'.so')。 注意:用户的问题中“包含'.so'的文件”可能有两种含义,但我们按照文件名包含“.so”字符串来解释,因为共享库文件通常以“.so”为标识。 因此,我们的答案是: </think> 在 Linux/OpenWrt 系统中,使用 shell 查找指定目录下所有子目录中包含 `.so` 文件方法如下,主要使用 `find` 命令实现: ### 一、基础查找方法 1. **查找所有后缀为 `.so` 的文件** 最简单的查找方式,匹配所有以 `.so` 结尾的共享库文件: ```bash find /your/target/directory -type f -name "*.so" ``` *示例输出:* ``` /your/target/directory/lib/main.so /your/target/directory/subdir/lib/util.so ``` 2. **查找文件名包含 `.so` 的文件** 匹配文件名中**包含** `.so` 的所有文件包括带版本号的库如 `libfoo.so.1.2.3`): ```bash find /your/target/directory -type f -name "*.so*" ``` --- ### 二、高级查找方法 1. **结合 `grep` 过滤内容** 查找包含特定字符串的 `.so` 文件(如引用[4]中的场景): ```bash find /your/target/directory -type f -name "*.so" -exec grep -l "ICTCLAS_FileProcess" {} + ``` *输出示例:* ``` /your/target/directory/libICTCLAS50.so ``` 2. **统计数量和详情** 组合命令实现统计和详情查看: ```bash # 统计数量 find /your/target/directory -type f -name "*.so" | wc -l # 显示文件详情 find /your/target/directory -type f -name "*.so" -exec ls -lh {} \; ``` --- ### 三、在 Makefile 中的集成 参考引用[3]的 Makefile 实现方式: ```makefile SO_DIRS := $(shell find $(SUBDIRS) -type d) SO_FILES := $(foreach dir,$(SO_DIRS),$(wildcard $(dir)/*.so)) all: @echo "Found SO files: $(SO_FILES)" # 后续处理... ``` --- ### 四、OpenWrt 特殊注意事 1. **精简环境适配** OpenWrt 默认无 `find`,需安装: ```bash opkg update opkg install findutils ``` 2. **路径大小写敏感** 嵌入式系统严格区分大小写: ```bash find /lib -iname "*.so" # -iname 忽略大小写 ``` --- ### 五、实用单行命令示例 ```bash # 查找并复制所有.so文件到backup目录 find ~/project -name "*.so" -exec cp {} ~/backup \; # 查找7天内修改过的.so文件 find /opt -name "*.so" -mtime -7 ``` > **提示**:若需递归查找源码中的字符串(如引用[4]),使用: > ```bash > grep -r "keyword" /target/directory --include="*.so" > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值