How can I use xargs to copy files that have spaces and quotes in their names?

后端 未结 22 1158
春和景丽
春和景丽 2020-12-02 03:49

I\'m trying to copy a bunch of files below a directory and a number of the files have spaces and single-quotes in their names. When I try to string together find

22条回答
  •  清歌不尽
    2020-12-02 04:15

    Frame challenge — you're asking how to use xargs. The answer is: you don't use xargs, because you don't need it.

    The comment by user80168 describes a way to do this directly with cp, without calling cp for every file:

    find . -name '*FooBar*' -exec cp -t /tmp -- {} +
    

    This works because:

    • the cp -t flag allows to give the target directory near the beginning of cp, rather than near the end. From man cp:
       -t, --target-directory=DIRECTORY
             copy all SOURCE arguments into DIRECTORY
    
    • The -- flag tells cp to interpret everything after as a filename, not a flag, so files starting with - or -- do not confuse cp; you still need this because the -/-- characters are interpreted by cp, whereas any other special characters are interpreted by the shell.

    • The find -exec command {} + variant essentially does the same as xargs. From man find:

       -exec command {} +                                                     
             This  variant  of the -exec action runs the specified command on
             the selected files, but the command line is built  by  appending
             each  selected file name at the end; the total number of invoca‐
             matched  files.   The command line is built in much the same way
             that xargs builds its command lines.  Only one instance of  `{}'
             is  allowed  within the command, and (when find is being invoked
             from a shell) it should be quoted (for example, '{}') to protect
             it  from  interpretation  by shells.  The command is executed in
             the starting directory.  If any invocation  returns  a  non-zero
             value  as exit status, then find returns a non-zero exit status.
             If find encounters an error, this can sometimes cause an immedi‐
             ate  exit, so some pending commands may not be run at all.  This
             variant of -exec always returns true.
    

    By using this in find directly, this avoids the need of a pipe or a shell invocation, such that you don't need to worry about any nasty characters in filenames.

提交回复
热议问题