10

When I run the following command:

> mkdir some_dir
> find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} some_dir

I get hundreds of lines that say:

mv: target `/foo/bar/XX.csv` is not a directory

Why? I thought xargs would execute:

mv /foo/barXX.csv some_dir

for every file that find finds. What's going on? By the way, this is with zsh

Update:

Update1:

I tried:

find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} -t some_dir

but then I got a few lines like:

mv: cannot stat `{}': No such file or directory

although I think the command is moving my files correctly.

Update2:

I don't seem to need the -t option when using mv alone. For example

> touch file1.txt
> touch file2.txt
> mkdir my_dir
> mv  file1.txt  file2.txt  my_dir

works well. Why do I need -t when using xargs?

2 Answers 2

15

Assuming you have GNU (find, xargs, & mv), change your command to this:

$ find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir

excerpt from mv man page

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

The above xargs ... will construct the command so that calls to move will be like this:

 $ mv 1.csv 2.csv 3.csv ... -t some_dir

Don't need xargs

You can skip this approach by just having find do all the work itself:

$ find /foot/bar/ -name '*.csv' -exec mv -t some_dir {} +

Why do you need the mv -t ...?

This has to do with the way that xargs is constructing the set of files to pass to the command it's going to run each time, (i.e. mv ...).

When you run the mv command manually yourself you control how many filenames are passed to it and so you don't need to worry about needing the -t my_dir since you always will put the destination directory last.

References

5
  • Thanks! This is very helpful. I am a bit confused though (see my Updates) Commented Jul 20, 2013 at 20:29
  • 1
    The constructed command is mv -t some_dir 1.csv 2.csv 3.csv ... so the file arguments are last. That's the error in the question, in order to use {} you have to pass -I {} to xargs. Commented Jul 20, 2013 at 21:03
  • Thanks. That explains everything. What about the second question I had in Update 2? Do you know why I don't need -t with multiple files and a directory with a regular mv? Commented Jul 20, 2013 at 22:45
  • 1
    @user815423426 - I'll update it later when I get a chance tonight, I do know why.
    – slm
    Commented Jul 20, 2013 at 23:47
  • @user815423426 - I updated the question, let me know if it makes sense wrt mv -t.
    – slm
    Commented Jul 21, 2013 at 12:40
1

You can also use the ls command instead of find command:

ls /foot/bar/*.csv | xargs  mv -t some_dir

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .