Search code examples
bashfind

From Bash I would like to use find to execute 2 commands on the same file, so I can output the file name and metadata about the file


From bash I need to execute 2 commands on specific files recursively. I am trying to print the filename and meta information at the same time. I need to combine the following 2 commands so first a filename is printed, then the metadata for that file is printed, and then repeat for the next file.

I print the file name with:

find . -wholename '*word/test.wsp -exec echo {} \;

And I print the meta-data with:

find . -wholename ‘*word/test\.wsp’ -exec whisper-info {} \;

However, the second command does not print the filename, so I am unsure which files the meta-data belongs to.

How can I execute the 2 commands simutaneously?

I've tried: find . -wholename '*word/test.wsp -exec echo {} && whisper-info {} \; find . -wholename '*word/test.wsp -exec echo && whisper-info {} \; find . -wholename '*word/test.wsp -exec echo {} && -exec whisper-info {} \; find . -wholename '*word/test.wsp -exec echo {} \; && whisper-info {} \; find . -wholename '*word/test.wsp -exec echo {} \; && -exec whisper-info {} \;

And a lot of other combinations.


Solution

  • -exec require a single command, but that command can be a shell that executes an arbitrary script consisting of your two commands.

    find . -wholename '*word/test.wsp' -exec sh -c 'echo "$1"; whisper-info "$1"' _ {} \;
    

    A few notes:

    • {} is not embedded in the command. Let the command be a static script that accepts an argument, instead.
    • _ is a dummy value used to set $0 in the shell.

    You can avoid spawning quite so many shells by including a loop in the shell to iterate over multiple arguments provided by find -exec ... +

    find . -wholename '*word/test.wsp' -exec sh -c 'for f; do echo "$f"; whisper-info "$f"; done' _ {} +
    

    for f; do ...; done is short for for f in "$@"; do ...; done.