Movendo arquivos aleatórios usando shuf e mv - Lista de argumentos muito longa

2

Eu tenho um diretório contendo quase 250 mil arquivos, que são muitos arquivos, e eu quero mover x arquivos aleatórios para outro diretório.

Eu pesquisei e obtive a solução de usar os comandos shuf e mv de aqui e aqui , então basicamente eu estou usando este comando

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

Mas estou recebendo este erro:

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

Acredito que por causa do grande número de arquivos, portanto, a lista de argumentos é muito longa. Existe outra maneira de fazer isso?

Estou usando o SLES12 SP2.

    
por Mostafa Hussein 03.09.2018 / 18:07

1 resposta

2

Como você está usando o SLES, pode usar as extensões do GNU para torná-lo mais seguro:

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

Isso usa find para processar listas de arquivos via em vez de argumentos de linha de comando, depois embaralha-as, limita a saída e finalmente as move para testB . As opções -print0 , -z e -0 garantem que os terminadores nul sejam usados em vez de novas linhas.

Em vez de find , você pode usar:

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

printf sendo incorporado em bash , ele não é afetado por essa limitação lista de argumentos por muito tempo da chamada de sistema execve() . Isso é potencialmente menos eficiente, já que o shell precisa construir a lista inteira e classificá-la, enquanto find exibe os caminhos de arquivos não classificados como aparecem.

    
por 03.09.2018 / 18:10