0

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?

zeno Zeng
  • 3
  • 2

3 Answers3

0

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.

  • 1
    It showed: "-bash: {}: No such file or directory". Can you explain a little of xargs -I {} ? – zeno Zeng Jun 19 '20 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 '20 at 15:58
  • You are right. I did not test it. Depending a bit on what bsub does, you can probably leave the <. – Jona Engel Jun 19 '20 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 – Jona Engel Jun 19 '20 at 18:05
0

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

0

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).

Chris Davies
  • 116,213
  • 16
  • 160
  • 287