34

I use the following line to find all sub-directories of the PWD and run svnadmin verify on each directory (I already know that they're Subversion repositories)

find ./* -maxdepth 0 -exec svnadmin verify {} \;

This works well, other than the fact that the output looks like this:

* Verifying repository metadata ...
* Verifying metadata at revision 1 ...
* Verifying metadata at revision 2 ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 9 ...
* Verifying metadata at revision 10 ...
* Verifying metadata at revision 12 ...
* Verifying metadata at revision 14 ...
* Verifying metadata at revision 15 ...
* Verifying metadata at revision 18 ...
* Verifying metadata at revision 20 ...
* Verifying metadata at revision 22 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.
* Verified revision 10.
* Verified revision 11.
* Verified revision 12.
* Verified revision 13.
* Verified revision 14.
* Verified revision 15.
* Verified revision 16.
* Verified revision 17.
* Verified revision 18.
* Verified revision 19.
* Verified revision 20.
* Verified revision 21.
* Verified revision 22.
* Verified revision 23.
* Verified revision 0.
* Verifying repository metadata ...
* Verifying metadata at revision 4 ...
* Verifying metadata at revision 5 ...
* Verifying metadata at revision 6 ...
* Verifying metadata at revision 7 ...
* Verifying metadata at revision 9 ...
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.
* Verified revision 3.
* Verified revision 4.
* Verified revision 5.
* Verified revision 6.
* Verified revision 7.
* Verified revision 8.
* Verified revision 9.

I'd really like find to print the filename before executing the svnadmin verify command, to make logging easier.

I've tried to squeeze a little ls in there but bodged it up, how should I do this (preferably simply)?

37

simply add a -printf option before

find -printf '%p' -exec command \;
  • 4
    Lovely, I changed '%p' to '%p\n' so that the name precedes the verify output on it's own line. – Arronical Jul 22 '15 at 12:06
  • 17
    @Arronical if that's the format you want, you could replace the (formatted) -printf '%p\n' with the simpler -print – steeldriver Jul 22 '15 at 12:56
  • 4
    find -name <a_name> -print -exec command {} \; – toliveira Mar 15 '17 at 10:53
14

If you don't want to recurse, there's no point in using find. It is far simpler to do it in the shell directly:

for d in */; do echo "$d"; svnadmin verify "$d"; done

The for d in */ will find all directories (the */ ensures only directories and no files are found); the echo "$d" will print the directory's name; the svnadmin verify "$d" will check the directory.

This can be run either directly from the command line or from within a script with no change in format.

  • 1
    This does look like a better way to achieve my goal, but I had to give the answer to Fiximan just because my title and question reference find so much. Thanks for improving my knowledge though! – Arronical Jul 22 '15 at 12:35
  • This requires using a glob. Globbing is definitely useful & powerful, but in my personal experience the syntax is more difficult to set up, and often ends up needing other things like dotglob and globstar in bash, which creates a longer, more complicated script. I tend to save globs for large complicated tasks, while find's syntax is easier to throw together on the fly by just stringing together a bunch of filters and commands into a one-liner. – user5359531 Jul 22 '16 at 19:32
  • @user5359531 neither globstar nor dotglob (unless you know you have hidden files and actually want them) are needed here. This is obviously a matter of opinion but you are the first person I've ever come across who considers the rather obtuse format of find simpler. I always prefer globs over find since I not only find them far simpler but they are also safer when dealing with arbitrary filenames that are passed to other programs. – terdon Jul 22 '16 at 19:49
6
find ./* -maxdepth 0 -type d -exec bash -c 'echo "{}"; svnadmin verify "{}"' \;

I have added -type d if it is only directories.

  • I'd quote {}, at least in svnadmin verify {} – kos Jul 22 '15 at 11:57
  • Thanks for the speedy response. So in this command does the -exec spawn a child shell, in which the 2 commands are run, using ; as end of line? – Arronical Jul 22 '15 at 12:00
5

Try this:

for f in * ; do echo  -n "${f}:"; svnadmin verify "${f}"; done

If you just want directories(Thanks to @kos note):

for f in */ ; do echo  -n "${f}:"; svnadmin verify "${f}"; done
  • Nice, but this will process also files: for f in */ will process only directories – kos Jul 22 '15 at 12:03
  • Will this only work in a script? Or can I issue it on the command line? – Arronical Jul 22 '15 at 12:07
  • 1
    @Arronical will work also as command line – Maythux Jul 22 '15 at 14:06
2
  • Use . -maxdepth 1 instead of ./*, you need only the first level in the folder structure
  • Use -type d, you need only folders
  • Use ! -name ".", you don't need .
  • Use -exec to start a shell
  • Use sh -c to start commands inside the shell

Your command

find . -maxdepth 1 -type d ! -name "." -exec sh -c 'echo "{}"; svnadmin verify "{}"' \;

or shorter

  • Use -prune if the file is a directory, do not descend into it

Your command

find . -mindepth 1 -prune -exec sh -c 'echo "{}"; svnadmin verify "{}"' \; 
  • -prune looks interesting. I used ./* -maxdepth 0 to avoid returning . from the find command. It doesn't cause any critical error, but I prefer not to have that in my output. – Arronical Jul 22 '15 at 13:13
1

find has option flags for printing, which are already mentioned in other answers. If we look at the problem form the perspective of executing multiple commands for the same currently processed file, find allows using multiple -exec statements. This means we could opt for using:

find ./* -maxdepth 0 -exec echo {} \; -exec svnadmin verify {} \; 

Again, note that this approach is applicable to not just printing with echo, printf, or other utilities, but also other commands.

0

It may be useful to pipe the find output to read loop:

find . | while read d; do echo "=== ${d}: ==="; svnadmin verify ${d}; done

It allows you to execute more complicated, compound command sequence with filenames returned by find, like in this fancy ls example:

find . | while read f; do echo ${f} | figlet -k; done
-1

This will print the name and contents of files-only recursively..

find . -type f -printf '\n\n%p:\n' -exec cat {} \;

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.