how to redirect result "!find ..." command to put lftp command how to redirect result "!find ..." command to put lftp command shell shell

how to redirect result "!find ..." command to put lftp command


I have read through the whole man lftp(1) and it seems that the way you have chosen is actually the best one.

  1. ! command doesn't support direct combination with another commands, as you tried put < !find ...
  2. The only way to upload files is using put, mput or mirror. mirror is of no use for you as you noted, because it preserves the path.
  3. put or mput commands don't support any means to specify a file with list of files to upload.

So, the only possibility is what you have: generate the script and use source to run it.

What you could try is to put all the files into one mput command:

!find ./local -type f | awk -v ORS=" " 'BEGIN{print "mput "}{print}' > /tmp/files.lftp

but be careful: although I haven't found it in the docs, there might be limitation for maximum line size! So I think in the end your way is the best way to go.

Note that you can also code-golf your command to:

!find ./local -type f -printf "put %p\n" > /tmp/files.lftp


source -e find ./local -type f \| sed \'s/^\(.*\)$/put \"\1\"/\'

The sed command surrounds each output line of find with double-quotes (") and prepends a put. This will work for filenames containing spaces and some other critical characters, but will fail for filenames containing double-quotes, line-breaks, ... You may extend the substituition performed by sed accordingliy, if you happen to have such characters in your filenames.

Note that the backslash (\) in front of the pipe sign (|), the double- and single-quotes are needed to escape interpretation by the lsftp command line parser. To test the command on a sh-like shell, use:

find ./local -type f | sed 's/^\(.*\)$/put "\1"/'


If you know the maximum depth of the local directory, you can use plain mput command like this:

lcd local && mput * */* */*/* */*/*/*