I have a folder with more than a million files that needs sorting, but I can't really do anything because mv
outputs this message all the time
-bash: /bin/mv: Argument list too long
I'm using this command to move extension-less files:
mv -- !(*.jpg|*.png|*.bmp) targetdir/
Best Answer
xargs
is the tool for the job. That, orfind
with-exec … {} +
. These tools run a command several times, with as many arguments as can be passed in one go.Both methods are easier to carry out when the variable argument list is at the end, which isn't the case here: the final argument to
mv
is the destination. With GNU utilities (i.e. on non-embedded Linux or Cygwin), the-t
option tomv
is useful, to pass the destination first.If the file names have no whitespace nor any of
\"'
, then you can simply provide the file names as input toxargs
(theecho
command is a bash builtin, so it isn't subject to the command line length limit; if you see!: event not found
, you need to enable globbing syntax withshopt -s extglob
):You can use the
-0
option toxargs
to use null-delimited input instead of the default quoted format.Alternatively, you can generate the list of file names with
find
. To avoid recursing into subdirectories, use-type d -prune
. Since no action is specified for the listed image files, only the other files are moved.(This includes dot files, unlike the shell wildcard methods.)
If you don't have GNU utilities, you can use an intermediate shell to get the arguments in the right order. This method works on all POSIX systems.
In zsh, you can load the
mv
builtin:or if you prefer to let
mv
and other names keep referring to the external commands:or with ksh-style globs:
Alternatively, using GNU
mv
andzargs
: