I am trying to move my files from current dir to another dir. The issue I am having is that multiple files have a name with special characters like space, ü, &, (, ...
. How can I move all my files using a command like: ls | grep mp4 | xargs -i mv {} mp4
, where {}
is supposed to be the name of the current file and mp4 the destination put all my file. I have tried the command but it shows errors. Can you please help ?

- 67,283
- 35
- 116
- 255

- 111
2 Answers
This is exactly the situation you don't want to use ls
in. Or xargs
with default settings, it will split the input on spaces, and handles quotes and backslashes specially. You'd need to use -0
to separate input on null bytes, or -d'\n'
to separate on newlines (GNU xargs) to turn that behaviour off.
As all the files are in the same directory, you can just use the shell:
mv *mp4* mp4/
Or mv *.mp4 mp4/
if you only meant files files that have mp4
as an extension. The first one would warn about moving mp4
itself to mp4
.)
If the files were not in the same directory, you'd need to either use the double-star (zsh
- enabled by default or ksh
with set -o globstar
or bash
with shopt -s globstar
):
mv **/*mp4* mp4/
or find
find . -type f -name "*mp*" -exec mv {} mp4/ \;

- 138,973
The command:
ls | grep mp4 | xargs -i mv {} mp4
can in most cases be replaced by the simpler and more robust:
mv *mp4* mp4
You can ignore the warning about the directory mp4 not being movable inside itself.
Note that this script, like yours, is moving all files having "mp4
" appearing anywhere in their name (e.g.: mp4list.txt
, lamp4.jpg
). Should you actually want to only move files with the extension ".mp4
", you can use:
mv *.mp4 mp4
That would prevent the situation leading to the error message about the directory mp4
itself to occur.
Should the number of mp4 files is huge and prevent the former command to work, you might use GNU find
to achieve the same:
find . -maxdepth 1 -name "*mp4*" -exec mv -t mp4 {} +
or
find . -maxdepth 1 -name "*.mp4" -exec mv -t mp4 {} +

- 61,204
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
– dmx Apr 15 '17 at 04:33echo "'foo bar' doo\ goo" | xargs -n1 echo
. – ilkkachu Apr 15 '17 at 09:49