2

For instance, want to match all files in this directory and sub-directories that end with .ly or .ily. So far, find . -name "*.*ly" -print is the closest I can get but this could potentially find files names I don't want.

3 Answers 3

6

You can use the -o option, which is an "or" option.

The simplest version would be

find . -name '*.ly' -o -name '*.ily'

This works because -print is the default action.

But if the -print was just an example then you might need to group the two clauses together

find . \( -name '*.ly' -o -name '*.ily' \) -print
2

zsh globs have a **/ recursive globbing operator and glob qualifiers so can do most of what find can do. Zero-or-one of something, aka optional something can be done with (|something) there (nothing or something), though there's also a (#cX,Y) similar to regex {X,Y} as an arbitrary interval operator (needs set -o extendedglob):

print -rC1 -- **/*.(|i)ly(N)

Would have the advantage over the find equivalent of giving you a sorted list, skipping hidden files (use the D qualifier if you want them), avoiding the ./ prefix, working with arbitrary file names (many find implementations including GNU find choke on file names that are not valid text in the user's locale) and generally makes it easier and safer to work with the list of files if you need more than printing them.

0

Another solution is to use -regex with those find implementations that support it:

With GNU find:

find -regex '.*\.i?ly'
# or the full command
find . -regextype posix-extended -regex '.*\.i?ly'

With BSD find:

find -E . -regex '.*\.i?ly'

The -regex option matches the whole path and is anchored at both start and end, so you need .* at the beginning and don't need $ at the end.

? is an extended regular expression operator (as in grep -E) that matches 0 or 1 of the preceding atom, here i. It's not available in basic regular expressions¹, so you need the -E in BSD find. In GNU find (at least in current versions), the default regex are neither basic nor extended regex, but some regex variant from some ancient version of emacs, where ? is supported. So that -regextype posix-extended is not necessary in this case here.


¹ \{0,1\} has been added to BREs as an equivalent of ERE ? later though.

3
  • 3
    This doesn't seem to exclude files ending in e.g. .ely.
    – Kusalananda
    May 22 at 6:37
  • 4
    use .*\.i?ly$ rather than .*/.*\..?ly. ./*/.* can be reduced to just .* (filenames output from find will always have a path), i? restricts it to an optional i after the . rather than any character, and the $ anchors the ly to the end of the filename (otherwise it will match anywhere in the filename - e.g. it would match "i.can.fly.txt")
    – cas
    May 22 at 8:35
  • @cas it matches the whole path so you don't actually need $
    – phuclv
    May 23 at 3:40

You must log in to answer this question.

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