Moving files with find + xargs: target is not a directory?
Solution 1
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
- mv GNU docs
- [one-liner]: Copying & Moving Files efficiently with xargs
- Why does find -exec mv {} ./target/ + not work?
Solution 2
You can also use the ls command instead of find command:
ls /foot/bar/*.csv | xargs mv -t some_dir
Related videos on Youtube
Amelio Vazquez-Reina
I'm passionate about people, technology and research. Some of my favorite quotes: "Far better an approximate answer to the right question than an exact answer to the wrong question" -- J. Tukey, 1962. "Your title makes you a manager, your people make you a leader" -- Donna Dubinsky, quoted in "Trillion Dollar Coach", 2019.
Updated on September 18, 2022Comments
-
Amelio Vazquez-Reina over 1 year
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 zshUpdate:
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 usingmv
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 usingxargs
? -
Amelio Vazquez-Reina almost 11 yearsThanks! This is very helpful. I am a bit confused though (see my Updates)
-
frostschutz almost 11 yearsThe 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
. -
slm almost 11 years@user815423426 - I'll update it later when I get a chance tonight, I do know why.
-
slm almost 11 years@user815423426 - I updated the question, let me know if it makes sense wrt
mv -t
.