如何在子目录中递归搜索文件

Sha*_*fiz 159 directory ls

我正在尝试查找XML特定目录中的所有文件以及其中的所有子目录(递归)。

ls -R *.xml仅列出当前目录中的文件。我很确定,子文件夹本身有几个.xml文件,但没有一个显示出来。

这是配置问题吗?

Kae*_*uCT 190

您只能使用find来做到这一点:

find . -name '*.xml'
Run Code Online (Sandbox Code Playgroud)

.是当前目录。如果需要在其他目录中搜索,请替换.为目录路径。

  • @mostafiz,`find` 命令递归搜索。如果您不引用参数,我认为您的 shell 可能会对 `*` 进行扩展,因此它将匹配当前目录中的文件。 (4认同)
  • 它是否在以当前目录为根的目录中递归搜索所需的文件。在我的情况下,它只检查当前目录,没有检查子目录。 (3认同)

Mit*_*tch 130

尝试使用查找

sudo find . -print | grep -i '.*[.]xml'
Run Code Online (Sandbox Code Playgroud)

  • -1 用于混合 `find` 和 `grep`,当 `find` 可以使用正则表达式和 glob 进行过滤,并且当你需要混合时不使用 `find` 的 `-print0` 和 grep 的 `-z`。 (13认同)
  • 只是出于兴趣。`find` 比 `ls -R` 有什么优势? (6认同)
  • sudo 是必须的,还是为了确保超级用户权限? (4认同)
  • 我让你决定。[须藤](http://s1296.photobucket.com/user/joetjo/media/2013-06-13_2340_zpsecf4b1de.png.html), [无须藤](http://s1296.photobucket.com/user/joetjo/媒体/2013-06-13_2340_001_zps4e3e080b.png.html)。 (4认同)

Roh*_*ain 17

试试这个命令:

ls -R | grep '.*[.]xml'
Run Code Online (Sandbox Code Playgroud)

ls没有过滤输出的选项。为此,您需要使用管道。这将输出从lsto传递grep,然后过滤它们以仅显示.xml文件。

  • 无论如何要让它显示它来自的目录? (7认同)
  • 必填链接:[为什么*不*解析`ls`?](https://unix.stackexchange.com/questions/128985) (3认同)

Ser*_*nyy 5

猛击

使用globstarshell 选项,我们可以使用递归通配符./**/*

bash-4.3$ shopt -s globstar
bash-4.3$ for i in  ./**/*.xml; do printf "%s\n" "$i" ; done
./adwaita-timed.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/META-INF/context.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/beans.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/web.xml
Run Code Online (Sandbox Code Playgroud)

珀尔

Perl 有一个模块Find,它允许递归目录树遍历。在特殊find()函数中,我们可以定义一个想要的子程序和我们想要遍历的目录,在这个例子中是.. 在这种情况下,单线将是:

bash-4.3$ perl -le 'use File::Find; find(sub{-f && $_ =~ /.xml$/ && print $File::Find::name},".")' 
./adwaita-timed.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml
Run Code Online (Sandbox Code Playgroud)

Python

Perl 有一个专门用于递归树遍历的完整模块,而 Python 有一个简洁的函数walk(),它是os模块的一部分,并重复返回最顶层路径的元组、所有子目录的列表和文件名列表。我们可以执行以下操作:

bash-4.3$ python -c 'import os,sys; [ sys.stdout.write(os.path.join(r,i)+"\n") for r,s,f in os.walk(".") for i in f if i.endswith(".xml") ]' 
./adwaita-timed.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml
Run Code Online (Sandbox Code Playgroud)

作为脚本,这可能要简洁得多:

bash-4.3$ shopt -s globstar
bash-4.3$ for i in  ./**/*.xml; do printf "%s\n" "$i" ; done
./adwaita-timed.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/META-INF/context.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/beans.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/web.xml
Run Code Online (Sandbox Code Playgroud)

其他答案提到find了递归遍历,这是这项工作的首选工具。需要提及的是find具有多个命令行开关的事实,例如-printf以所需格式打印输出,-type f仅查找常规文件,-inum按 inode 编号-mtime搜索,按修改日期搜索,-exec <command> {} \;执行特定命令来处理文件将文件作为参数传递(其中{}find当前文件的标准占位符)以及许多其他文件,因此请阅读find.