1

Consider this directory (and file) structure:

mkdir testone
mkdir testtwo
mkdir testone/.svn
mkdir testtwo/.git
touch testone/fileA
touch testone/fileB
touch testone/fileC
touch testone/.svn/fileA1
touch testone/.svn/fileB1
touch testone/.svn/fileC1
touch testtwo/fileD
touch testtwo/fileE
touch testtwo/fileF
touch testtwo/.git/fileD1
touch testtwo/.git/fileE1
touch testtwo/.git/fileF1

I would like to print/find all files which are in these two directories, but excluding those in the subdirectories .git and/or .svn. If I do this:

find test*

... then all the files get dumped regardless.

If I do this (as per, say, https://askubuntu.com/questions/266179/how-to-exclude-ignore-hidden-files-and-directories-in-a-wildcard-embedded-find):

$ find test* -path '.svn' -o -prune 
testone
testtwo
$ find test* -path '*/.svn/*' -o -prune 
testone
testtwo

... then I get only the top-level directories dumped, and no filenames.

Is it possible to use find alone to perform a search/listing like this, without piping into grep (i.e. doing a find for all files, then: find test* | grep -v '\.svn' | grep -v '\.git'; which would also output the top-level directory names, which I don't need)?

1

Your find commands not saying what to do if the given path is not matched. If you want to exclude everything that starts with a dot, and print the rest try:

find test* -path '*/.*' -prune -o -print

so it'll prune anything that matches that path, and print anything that doesn't.

Example output:

testone
testone/fileC
testone/fileB
testone/fileA
testtwo
testtwo/fileE
testtwo/fileF
testtwo/fileD

If you want to specifically exclude just .svn and .git but not other things that start with a dot you can do:

find test* \( -path '*/.svn' -o -path '*/.git' \) -prune -o -print

which for this example produces the same output

if you want to exclude the top level directories you can add -mindepth 1 like

find test* -mindepth 1 -path '*/.*' -prune -o -print

which gives

testone/fileC
testone/fileB
testone/fileA
testtwo/fileE
testtwo/fileF
testtwo/fileD
  • Many thanks @EricRenouf - that works great, I just had to add type f: ... -prune -o -type f -print so as to get rid of the top level directories... Cheers! – sdaau Nov 23 '16 at 13:00
  • @sdaau that will get rid of the top level directories, but would also get rid of any subdirectories themselves if you had any. It may be what you want, but it will exclude more than just the top level directories by adding -type f – Eric Renouf Nov 23 '16 at 13:02
1

As a complement to Eric's answer, find can accept the ! operator to invert predicates. There is also the -wholename test that will perform a match on the files including their paths. So you could write something like this:

find test* \( ! -wholename "*/.git/*" -a ! -wholename "*/.svn/*" \)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.