32

I'm just trying to move a bunch of files (not symlinks) out of my /etc/apache/sites-enabled folder into the /etc/apache/sites-available folder with the following:

/etc/apache2/sites-enabled$ find . -maxdepth 1 -type f | xargs mv {} ../sites-available/

but I'm an ubuntu n00b and am getting this error:

mv: target `./real-file' is not a directory

where 'real-file' is a test file I've set up on my dev environment. I'm trying to tidy up someone else's mess on a production server ;-)

Avinash Raj
  • 80,446
Rob
  • 465

4 Answers4

46

You could try the -exec option with find command,

/etc/apache2/sites-enabled$ sudo find . -maxdepth 1 -type f -exec mv {} /etc/apache2/sites-available \;

For moving files owned by root, you need sudo permissions.

If you want to use xargs command then add -I option to it.

find . -maxdepth 1 -type f | sudo xargs -I {} mv {} /etc/apache2/sites-available/
Avinash Raj
  • 80,446
14

Ideally you should use -print0 with find, so filenames with spaces don't screw things up.

E.g. this should work :

find . -whatever-flags-go-here -print0 | xargs -r0 mv -t target-directory

mv -t is directly usable with xargs as the source files are at the end of the argument list:

   mv [OPTION]... -t DIRECTORY SOURCE...

-t, --target-directory=DIRECTORY move all SOURCE arguments into DIRECTORY

Marki555
  • 103
2

you can also use another way to perform the same but with an extra performance:

find . -maxdepth 1 -type f -exec mv -t /etc/apache2/sites-available {} \+

Note that it ends with \+ which means for the find command to get the output and expand into {} doing what you want, in this way you avoid the two options (\; = for each entry AND piping into a new command xargs)

Here is the explanation (you can also check the manual 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 invocations of the command will be much less than the number of 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. The command is executed in the starting directory.

Roland
  • 103
0

For me, my version of mv didn't had -t option and my version of xargs didn't had -I option. I couldn't even use -exec in find as first I had to filter those results. So this is what I used:

for f in $(find -type f | grep 'key')
do
mv $f dest/
done