find's prune's -path is not taking wildcards

Unix & Linux Asked by Pompy on December 8, 2020

i want to exclude one directory from the find search tree. .aaa is a hidden sub-directory in the current directory. I want to exclude aaa_rc_bbb, xxx_rc_xxx and many more sub-directories containing rc in their names. But it still not ignoring and giving me results containing rc sub-directories. Its as if *rc* wildcard is not working.

find -L /students/projects/myname/ -name .aaa -prune -o -path */*/class_project/*/*/pikachu/*/*/*rc*/ -prune -o -path */*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt | head -n50 | xargs ls.

Also, i want find to search only in this path : */*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt

Please help me. Am i doing anything wrong?

2 Answers

Your -path pattern ends with a slash. No pathname that find examines will ever end in a slash, so the pattern will never match anything.

To prune any directory called .aaa and any directory with rc in its name:

find -L /students/projects/myname 
    -type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o -print

To only look at the path */*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt:

find -L /students/projects/myname 
    -type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o 
    -path '*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt' -print

This assumes that bambi.txt is located in


Note the quoting of the patterns in the find command. Without quotes, the shell would try to expand the patterns to lists of pathnames before calling find, possibly resulting in confusing find, or with some shells, an error.

Answered by Kusalananda on December 8, 2020

The first issue is that you have unquoted globs (*). All those paths should be surrounded with single quotes, e.g. '*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt'. This prevents the shell from expanding the wildcards before they get passed to find.

Next, you need the -prune sub-expression to occur before the main search sub-expression. BTW, you can combine all the names into a compound expression with a single -prune like this:

find ( ( -name '*foo*' -o -name '*bar*' ) -a -prune ) -o ( -name baz -a -print )

This means I want to find files named baz while excluding any files/directories containing foo or bar in their names.

Some notes:

  • I'm being liberal with the -a (AND) operator and the parentheses so there is no ambiguity.
  • Parentheses, which act to change precedence just like with most other expression types, are escaped with so they are not interpreted by the shell before being passed to find.
  • I'm using two -name tests but any other tests (e.g. -path) can be in the first nested set of parentheses. Any file/dir matching any of the tests will be pruned and thus not applied to the next tests (in the last set of parens).
  • It's a good idea to be explicit with the -print action to distinguish it from the -prune part.

For clarity let's rewrite this in a more common expression style:

((name=='*foo*' OR name=='*bar*') AND prune) OR (name==bar AND print)

or even

if (name=='*foo*' OR name=='*bar*')
else if (name==bar)

Now given normal precedence rules and that the default boolean operator is -a we can reduce the example down to:

find ( -name '*foo*' -o -name '*bar*' ) -prune -o -name baz -print

Turning to your command, the paths that find constructs for the files it discovers will never end in / characters, so -path '*/*/class_project/*/*/pikachu/*/*/*rc*/' could never possibly match. You'd need to drop that trailing / and possibly add a -type d if you want to restrict to files of type directory.

Also note that */* as a pattern matches on any string that contains a /, that also includes foo/bar/baz. Here, your paths all start with /students/projects/myname/ so the / in */* is redundant as we know already that that / will be there.

If I'm reading your intent correctly you don't have any tests for the second sub-expression, i.e. if a file doesn't get pruned you want to print it. So that leads to

find -L /students/projects/myname/ 
       -name .aaa 
    -o -path '*/class_project/*/*/pikachu/*/*/*rc*' 
    -o -path '*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt' 
  ) -prune 
  -o -print

Answered by B Layer on December 8, 2020

Add your own answers!

Related Questions

All processes running on the same core

1  Asked on December 24, 2020 by roofkiller


capturing yum update transaction to replicate on another machine

0  Asked on December 23, 2020 by dan-schneider


Add Support CRAM-MD5 or DIGEST-MD5 to SMTP server

0  Asked on December 22, 2020 by alpav99


Linux delete lines from ini-file where key has no value

1  Asked on December 21, 2020 by sunwave121


What caused traffic on port 631?

0  Asked on December 21, 2020 by u20200411


Bind/Unbind Linux Module Automatically

1  Asked on December 20, 2020 by vladius


ls everything that is _not_ a symlink

1  Asked on December 20, 2020


Netgear39 Removal

0  Asked on December 20, 2020 by danny-bender


Join two csv files by matching columns, join command

1  Asked on December 20, 2020 by cdxun


Arithmetic on values with memory size units

4  Asked on December 20, 2020 by malan


case while option not showing last argument in shell script

1  Asked on December 19, 2020 by user2358844


Debian update to Buster, iptables throwing an error in

1  Asked on December 19, 2020 by jademalo


Logitech Marble Mouse – Linux Scroll Modifier Setup

3  Asked on December 18, 2020 by peter-l


ZFS setup, adding drives on the go

0  Asked on December 18, 2020 by timyorgut


Linux Font “Lato” is not available to the JVM

0  Asked on December 18, 2020 by valene


Ask a Question

Get help from others!

© 2023 All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP