7

I'm trying to find all the project files of a particular file type with:

ls -ltR *.mb

I know there are the files I want in several folders, but I get no results back. What did I do wrong?

2 Answers 2

17

ls doesn't match patterns. It simply lists the files or folders in the input arguments. *.mb is expanded by the shell before passing to ls, therefore if there are no files named *.mb in the current directory, nothing will be output, otherwise only files in the current directory will be output

The standard way to list files recursively is to use find

find . -name '*.mb' -type f -printf "%-.22T+ %M %n %-8u %-8g %8s %Tx %.8TX %p\n" | sort | cut -f 2- -d ' '

This way you can customize the output list format as you want. See: List files by last edited date


An alternative way is to use globstar which can be enabled with shopt -s globstar

ls -ltR **/*.mb

The first **/ will match any arbitrary subdirectory paths. Then *.mb with match your files in those directories

  • globstar

    If set, the pattern ** used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a /, only directories and subdirectories match.

https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

2
  • globstar also works to then remove the files rm -R **/*.mb
    – swihart
    Jun 3, 2020 at 13:55
  • @swihart obviously, because globstar is a shell feature and has nothing to do with the commands. The commands only receive a list of expanded files from the shell, as said, they know nothing about the pattern you typed
    – phuclv
    Oct 22, 2022 at 3:14
2

@phuclv has two good options. When I need to do similar, I typically pipe the output of ls to grep like this:

ls -ltR | grep .*\.mb

this sends the output of ls to the input of grep instead of outputting to stdout, and grep then outputs only the lines that contain at least one match for the regular expression.

The regex

.*\.mb

can be explained as:

.: match any character
*: preceding character or group should appear 0 or more times
\.mb: literally .mb
3
  • 2
    This is not really a good alternative to a simple and robust find . -name "*.mb" – particularly if you want to do anything with the found files.
    – slhck
    Mar 22, 2019 at 19:52
  • 1
    Don't parse ls. Another bug: unquoted .*\.mb will undergo globbing. Sole existence of file(s) like .foo.mb or .bar.mb will change your command in a way you didn't expect. Mar 22, 2019 at 20:18
  • 1
    Why not parse ls (and what do to instead)?. Another bug: .*\.mb will match the string .mb anywhere in the name instead of only at the end
    – phuclv
    Mar 23, 2019 at 1:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .