如何递归遍历目录树并只查找文件?

3

我正在处理一个通过scp下载远程系统上文件夹的问题。下载下来的文件夹中包含有子文件夹,这些子文件夹中有大量文件,我需要将它们作为参数传递给Python脚本,如下所示:

scp -r researcher@192.168.150.4:SomeName/SomeNameElse/$folder_name/ $folder_name/
echo "File downloaded successfully"
echo "Running BD scanner"
for d in $folder_name/*; do
        if [[ -d $d ]]; then
                echo "It is a directory"
        elif [[ -f $d ]]; then
                echo "It is a file"
                echo "Running the scanner :"
                 python bd_scanner_new.py /home/nsadmin/Some/bash_script_run_files/$d
        else
                echo "$d is invalid file"
                exit 1
        fi
done

我已经添加了逻辑来查找是否有任何目录并将其排除在外。但是,我不会递归地遍历这些目录。

以下是部分结果:

File downloaded succesfully
Running BD scanner
It is a directory
It is a directory
It is a directory
Exiting

我希望你能改进这段代码,以使其遍历所有目录并获取所有文件。如果有任何建议,请帮忙提供。
2个回答

3
您可以在Bash 4.0+中使用shopt -s globstar:
#!/bin/bash

shopt -s globstar nullglob
cd _your_base_dir
for file in **/*; do
  # will loop for all the regular files across the entire tree
  # files with white spaces or other special characters are gracefully handled
  python bd_scanner_new.py "$file"
done

Bash手册中关于globstar的说明如下:

如果设置了,文件名扩展上下文中使用的模式 '**' 将匹配所有文件和零个或多个目录和子目录。如果模式后跟 '/',则只有目录和子目录匹配。

更多关于globstar的讨论请参见:https://unix.stackexchange.com/questions/117826/bash-globstar-matching


1
为什么要使用文件匹配时麻烦地使用通配符(globbing),而不是使用专门用于此目的的find命令,通过使用进程替换(<())与while循环。
#!/bin/bash

while IFS= read -r -d '' file; do
    # single filename is in $file
    python bd_scanner_new.py "$file"
done < <(find "$folder_name" -type f -print0)

这里,find会递归搜索从提到的路径到任何子目录的所有文件。文件名可以包含空格、制表符、空白和换行符。为了以安全的方式处理文件名,使用带有-print0的find:文件名与所有控制字符一起打印,并以NUL终止,然后read命令使用相同的分隔符进行处理。
注意; 顺便说一句,在bash中始终要对变量加双引号,以避免shell扩展。

为什么要使用while/read循环来解析find的输出(并使用非标准特性),而不是使用find-exec开关?:) - gniourf_gniourf
如果目录中有大量文件,并且对每个文件执行的函数很慢,那么使用find命令将会创建一个大型管道文件或消耗大量内存。 - Kevin Whitefoot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接