Search code examples
linuxshellfindxargs

How do I run find and cp commands concurrently in Linux?


How do I run find and cp commands concurrently? I have tried this:

find -name "*pdf*" | xargs cp $1 ./

But it doesn't work.


Solution

  • Use -exec option:

    find ./ -name "*pdf*" -exec cp -t . {} \+
    

    The {} is replaced with the current file names being processed.

    From the man page for find:

    -exec command {} +

    ...the command line is built by appending each selected file name at the end.. The command line is built in much the same way that xargs builds its command lines.

    Note the use of -t (target directory) option (which is a GNU extension). We cannot use -exec cp {} . +, because the matched file names are appended to the end of the command line, while destination would have to be specified last. Another workaround is to invoke sh:

    find ./ -name "*pdf*" -exec sh -c 'cp "$@" .' '' {} +
    

    I have habitually escaped the + character. Note, you should escape special characters of the find syntax to protect them from expansion by the shell. In particular, there is likely no need in backslash before +, because most shells will interpret it as a string (it will not be expanded to something different). However, you will definitely have to escape/quote the ; (which applies the command to each file sequentially):

    find -name "*pdf*" -exec cp -f {} . ';'