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
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
-
Thanks! This is very helpful. I am a bit confused though (see my Updates)Amelio Vazquez-Reina– Amelio Vazquez-Reina2013年07月20日 20:29:41 +00:00Commented Jul 20, 2013 at 20:29
-
1The 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 {}
toxargs
.frostschutz– frostschutz2013年07月20日 21:03:15 +00:00Commented 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 regularmv
?Amelio Vazquez-Reina– Amelio Vazquez-Reina2013年07月20日 22:45:52 +00:00Commented Jul 20, 2013 at 22:45 -
1@user815423426 - I'll update it later when I get a chance tonight, I do know why.2013年07月20日 23:47:34 +00:00Commented Jul 20, 2013 at 23:47
-
@user815423426 - I updated the question, let me know if it makes sense wrt
mv -t
.2013年07月21日 12:40:43 +00:00Commented Jul 21, 2013 at 12:40
You can also use the ls command instead of find command:
ls /foot/bar/*.csv | xargs mv -t some_dir