2

I have a directory containing nearly 250K files, which are lots of files, and I want to move x random files to another directory.

I searched and I got the solution of using the shuf and mv commands from here and here, so basically I am using this command

$ shuf -n 5533 -e trainB/* | xargs -i mv {} testB/

But I'm receiving this error:

bash: /usr/bin/shuf: Argument list too long

I believe because of the large number of files, so accordingly, the argument list is too long, is there another way to do this?

I'm running on SLES12 SP2.

2

Since you’re using SLES, you can use GNU extensions to make this safer:

find trainB -mindepth 1 -maxdepth 1 ! -name '.*' -print0 |
  shuf -n 5533 -z |
  xargs -r0 mv -t testB

This uses find to process file lists via pipes instead of command-line arguments, then shuffles them, limiting the output, and finally moves them to testB. The -print0, -z, and -0 options ensure nul terminators are used instead of newlines.

Instead of find, you can use:

printf '%s\0' trainB/*

printf being built-in in bash, it is not affected by that arg list too long limitation of the execve() system call. That's potentially less efficient though as the shell needs to build the whole list and sort it while find displays the file paths unsorted as they come.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.