I intend to find *.lsf following the current /subdirectories and execute bsub<*.lsf for all the find files. I tried:

find ./ -type f -name "*.lsf" -exec bsub < \;

The part find ./ -type f -name "*.lsf" works fine. However, the execute part has problems.

Can anyone helps figure out?


You were nearly there with your first attempt. What you need to do is to invoke a shell to parse the < redirection operator

find -name '*.lsf' -exec bash -c 'bsub <"$1"' _ {} \;

However, this isn't very efficient as you are now starting a shell for every matched file. Invoke the shell as few times as possible and use a loop to process multiple files at once

find -name '*.lsf' -exec bash -c 'for i in "$@"; do bsub <"$i"; done' _ {} +

Both of these are filename-safe (i.e. they handle whitespace and non-printing/semi-printing characters in file names).

| improve this answer | |
  • thank you a lot! – zeno Zeng Jul 3 at 11:51

You could work with xargs:

find ./ -type f -name "*.lsf" | xargs bsub

In fact, you could shorten the hole thing to:

find *.lsf | xargs bsub

Comment: Tested on the cluster I use.

Edit: Removed replacement string option and redirection character.

| improve this answer | |
  • 1
    It showed: "-bash: {}: No such file or directory". Can you explain a little of xargs -I {} ? – zeno Zeng Jun 19 at 15:49
  • 1
    You did not test that. It can't work, as the < and it right hand side operator, will be evaluated before the programs are executed. – ctrl-alt-delor Jun 19 at 15:58
  • You are right. I did not test it. Depending a bit on what bsub does, you can probably leave the <. – 2419 Jun 19 at 17:54
  • xargs -I {} tells xargs to replace the string {} with what it gets from standard input. In this case stdin is the pipe |. Which redirects the standard output from find. TThe replacement string does not have to be {}, it can be anything you chose. {} is just common. This is all in the man pages – 2419 Jun 19 at 18:05

Using xargs, in a way that works. (Note as @KamilMaciorowski said, this is unsafe.)

find . -type f -iname "*.lsf" | xargs -I {} bash -c 'cat < {}'

Then fixing for file-names spaces etc

find . -type f -iname "*.lsf" -print0 | xargs -0 -I {} bash -c 'cat < {}'

I tested with cat. You will have to replace with your command

| improve this answer | |

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.