How to Search for Files Recursively into Subdirectories
Solution 1
Try using Find
sudo find . -print | grep -i '.*[.]xml'
Solution 2
You can do it with find only:
find . -name '*.xml'
.
is the current directory. If you need to search in another directory, replace .
with the directory path.
Solution 3
Try this command:
ls -R | grep '.*[.]xml'
ls
doesn't have options to filter the output. For that you would need to use pipe. This passes the output from ls
to grep
, which then filters them to show just the .xml
files.
Solution 4
bash
Using globstar
shell option, we can make use of recursive globbing ./**/*
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
Perl
Perl has a module Find
, which allows for recursive directory tree traversal. Within the special find()
function, we can define a wanted subroutine and the directory that we want to traverse, in this example that's .
. The one-liner in such case would be:
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
Python
While Perl has a whole module dedicated to recursive tree traversal, Python has a neat function walk()
that is part of os
module, and repeatedly returns tuple of topmost path, list of all subdirectories, and list of filenames. We can do the following:
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
This might be far neater as a script:
#!/usr/bin/env python
import os,sys
for r,s,f in os.walk("."):
for i in f:
if i.endswith(".xml")
print(os.path.join(r,i))
find
Other answers have mentioned find
for recursive traversal, and that's the go-to tool for the job. What does need mention is the fact that find
has multiple command line switches, such as -printf
to print output in desired format, -type f
to find only regular files, -inum
to search by inode number, -mtime
to search by modification date, -exec <command> {} \;
to execute a particular command to process the file with passing file as argument ( where {}
is standard find
placeholder for current file) , and many others so please read the manpage for find
.
Related videos on Youtube
Shamim Hafiz - MSFT
Trying to catch up with and fill in the technological blanks...
Updated on September 18, 2022Comments
-
Shamim Hafiz - MSFT over 1 year
I am trying to look for all
XML
files in a particular directory and all sub-directories (recursively) inside it.ls -R *.xml
is only listing files in the current directory. I am quite sure, the sub-folders themselves have several.xml
files, but none are showing up.Is this a configuration issue?
-
KeyC0de about 7 yearsYou can do
ls -R | grep .xml
-
-
Shamim Hafiz - MSFT about 11 yearsis the sudo must, or it's there to ensure super user privileges?
-
Mitch about 11 years
-
don.joey about 10 yearsJust out of interest. What is the advantage of
find
overls -R
? -
Mitch about 10 years@don.joey This might help stackoverflow.com/questions/13830036/…
-
Mostafiz Rahman over 9 yearsDoes it search for the required file recursively in the directory rooted at current directory. In my case it just checked in the current directory only, didn't check the subdirectory.
-
KaeruCT over 9 years@mostafiz, you need to quote the '*.xml' part. I'll edit my answer.
-
Rodislav Moldovan over 9 years@ShamimHafiz, sudo is useful if you need to search in a location where your current user does not have read right, I think this was the reason why sudo was included in command, just to be sure that you'll get all possible results
-
Mostafiz Rahman over 9 yearsActually I searched for
.php
files in current directory. But it returned only.php
files in current directory, didn't searched recursively in sub-directories. That's why I'm asking whetherfind
command searches recursively or not. -
KaeruCT over 9 years@mostafiz, the
find
command searches recursively. If you don't quote the parameter, I think your shell might do an expansion on the*
, so it will match the files in the current directory. -
Mostafiz Rahman over 9 yearsAll right! May be I'd made some mistake. Now it is working perfectly!
-
muru about 9 years-1 for mixing
find
andgrep
, whenfind
can do filtering using both regexes and globs, and not usingfind
's-print0
and grep's-z
when you do need to mix. -
user1767754 almost 9 yearsWhat is the print statement for, when removing it or not, the result is the same.
-
AdamO almost 9 yearsAnyway to get this to show the directory it came from?
-
Christian over 7 years@Mitch the image hosting site you are using is blocked from where I am. Can you please share what the images were showing...? :)
-
Mitch over 7 years
-
Kip over 7 yearsyou can use
-regex
or-iregex
instead of-name
if you want to use a regex. -
Iluvathar about 7 yearsMandatory link: Why not parse
ls
? -
wogsland almost 7 yearsAwesomesauce. Simple and effective!
-
George Birbilis over 6 yearsthanks, needed that in Raspbian, combined with |shuf -n 1 at the end to pick one file randomly from the recursive list (to play a random .mp3 file from a folder hierarchy if some motion sensor was on)