[linux] Why does find -exec mv {} ./target/ + not work?

I want to know exactly what {} \; and {} \+ and | xargs ... do. Please clarify these with explanations.

Below 3 commands run and output same result but the first command takes a little time and the format is also little different.

find . -type f -exec file {} \;
find . -type f -exec file {} \+
find . -type f | xargs file

It's because 1st one runs the file command for every file coming from the find command. So, basically it runs as:

file file1.txt
file file2.txt

But latter 2 find with -exec commands run file command once for all files like below:

file file1.txt file2.txt

Then I run the following commands on which first one runs without problem but second one gives error message.

find . -type f -iname '*.cpp' -exec mv {} ./test/ \;
find . -type f -iname '*.cpp' -exec mv {} ./test/ \+ #gives error:find: missing argument to `-exec'

For command with {} \+, it gives me the error message

find: missing argument to `-exec'

why is that? can anyone please explain what am I doing wrong?

This question is related to linux find cygwin exec

The answer is


no, the difference between + and \; should be reversed. + appends the files to the end of the exec command then runs the exec command and \; runs the command for each file.

The problem is find . -type f -iname '*.cpp' -exec mv {} ./test/ \+ should be find . -type f -iname '*.cpp' -exec mv {} ./test/ + no need to escape it or terminate the +

xargs I haven't used in a long time but I think works like +.


The standard equivalent of find -iname ... -exec mv -t dest {} + for find implementations that don't support -iname or mv implementations that don't support -t is to use a shell to re-order the arguments:

find . -name '*.[cC][pP][pP]' -type f -exec sh -c '
  exec mv "$@" /dest/dir/' sh {} +

By using -name '*.[cC][pP][pP]', we also avoid the reliance on the current locale to decide what's the uppercase version of c or p.

Note that +, contrary to ; is not special in any shell so doesn't need to be quoted (though quoting won't harm, except of course with shells like rc that don't support \ as a quoting operator).

The trailing / in /dest/dir/ is so that mv fails with an error instead of renaming foo.cpp to /dest/dir in the case where only one cpp file was found and /dest/dir didn't exist or wasn't a directory (or symlink to directory).


I encountered the same issue on Mac OSX, using a ZSH shell: in this case there is no -t option for mv, so I had to find another solution. However the following command succeeded:

find .* * -maxdepth 0 -not -path '.git' -not -path '.backup' -exec mv '{}' .backup \;

The secret was to quote the braces. No need for the braces to be at the end of the exec command.

I tested under Ubuntu 14.04 (with BASH and ZSH shells), it works the same.

However, when using the + sign, it seems indeed that it has to be at the end of the exec command.


find . -name "*.mp3" -exec mv --target-directory=/home/d0k/??????/ {} \+

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to find

Find a file by name in Visual Studio Code Explaining the 'find -mtime' command find files by extension, *.html under a folder in nodejs MongoDB Show all contents from all collections How can I find a file/directory that could be anywhere on linux command line? Get all files modified in last 30 days in a directory FileNotFoundError: [Errno 2] No such file or directory Linux find and grep command together find . -type f -exec chmod 644 {} ; Find all stored procedures that reference a specific column in some table

Examples related to cygwin

How to install MinGW-w64 and MSYS2? Split text file into smaller multiple text file using command line fatal: early EOF fatal: index-pack failed Git Extensions: Win32 error 487: Couldn't reserve space for cygwin's heap, Win32 error 0 How to cd into a directory with space in the name? Git push hangs when pushing to Github? Running a shell script through Cygwin on Windows Running Git through Cygwin from Windows .ssh directory not being created Cygwin - Makefile-error: recipe for target `main.o' failed

Examples related to exec

I do not understand how execlp() works in Linux Running a Python script from PHP How do I execute a Shell built-in command with a C function? What are the uses of the exec command in shell scripts? php exec() is not executing the command How to call execl() in C with the proper arguments? Run Bash Command from PHP PHP shell_exec() vs exec() Ruby, Difference between exec, system and %x() or Backticks How to execute an external program from within Node.js?