I tried to find files and move them to another folder

$ find ~ -iregex ".*cheat.*\.pdf" -exec mv "{}" cheatSheet +
find: missing argument to `-exec'

However, the test works

find ~ -iregex ".*cheat.*\.pdf" -exec echo {} +

What's the problem with my usage?

  • The given answers are incorrect (refer to POSIX). Looks like your problem is the quotes. – Thomas Dickey Nov 11 '18 at 16:29

When using -exec ... {} +, the {} must be at the end, just before the +.

This means that you would have to use

-exec mv -t cheatSheet {} +

which would require access to GNU mv. Without GNU mv, you would use

-exec mv {} cheatSheat \;

to move one file at a time, or

-exec sh -c 'mv "$@" cheatSheet' sh {} +

to call an in-line script that moves all files in one go.

You additionally don't need -iregex. The following will be easier to read and understand:

find "$HOME" -ipath '*cheat*.pdf' \
    -exec sh -c 'mv "$@" cheatSheet' sh {} +

or, for clarity, either one of the following which does what you actually mean (it depends on whether you want cheat to be part of the filename at the end of the path (the first alternative), or one of the directory names in the path (the second alternative)):

find "$HOME" -iname '*cheat*.pdf' \
    -exec sh -c 'mv "$@" cheatSheet' sh {} +

find "$HOME" -ipath '*cheat*/*' -iname '*.pdf' \
    -exec sh -c 'mv "$@" cheatSheet' sh {} +

Note that -ipath is a GNU find extension, but that -iname, though non-standard, is more commonly implemented.



The {} needs to be a the end of the -exec command. The mv command supports this with the -t option:


So your command would be:

find ~ -iregex ".*cheat.*\.pdf" -exec mv -t cheatSheet "{}" +

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.