7 votos

Mover sólo los últimos 8 archivos de un directorio a otro directorio

Estoy tratando de mover los últimos 8 archivos del Documents a otro directorio, pero no quiero moverlos uno por uno a ese directorio específico. ¿Es posible moverlos con un sustituto del tail pero para directorios en lugar de archivos? Me refiero a que me gustaría hacerlo con algo como tail -8 ./Documents | mv ./Anotherdirectory o con mv tail -8 ./Documents ./Anotherdirectory .

De hecho, estoy buscando una forma inteligente en la que pueda mover los últimos 8 archivos (que aparecen en ls ) rápidamente (sin teclear cada nombre) al otro directorio. ¿Alguna sugerencia?

7voto

Zanna Puntos 502

Puede utilizar for que hace un bucle sobre los archivos de forma ordenada, y nos permite evitar el análisis de la salida de find o ls para evitar problemas con los espacios y otros caracteres especiales en los nombres de archivo. Muchas gracias a @muru por mejorar esto :)

i=0; j=$(stat ~/Documents/* --printf "%i\n" | wc -l); for k in ~/Documents/*; do if (( (j - ++i) < 8 )); then echo mv -v "$k" ~/AnotherDirectory; fi; done 

Pruébelo primero con echo y luego eliminar echo para mover realmente los archivos.

Como un script:

#!/bin/bash
i=0
j=$(stat ~/Documents/* --printf "%i\n" | wc -l )
for k in ~/Documents/*; do
  if (( (j - ++i) < 8 )); then
    echo mv -v -- "$k" ~/AnotherDirectory
  fi
done

de nuevo, eliminar echo después de las pruebas para mover los archivos de verdad

Explicación

3voto

t-mager Puntos 31

Puedes hacer cosas como esta usando la sustitución de comandos. En Bash:

mv $(ls -d [sort options] source/* | tail -n8) destination

El $(command) ejecutará lo que esté encerrado en él y sustituirá la salida de texto en el comando externo. Que ls imprimirá la ruta de cada archivo en el directorio fuente ordenado según las banderas que especifique, una por línea, así tail puede tomar los últimos. Así, lo anterior se ampliaría a

mv source/file1 source/file2 source/file3 ... source/file8 destination

Sólo tiene que ejecutar ls -d [sort options] source/* | tail -n8 para ver qué archivos copiará.

Dependiendo de cómo se ordene la salida de ls y la nomenclatura de los archivos, es posible que pueda hacer lo que busca de forma más sencilla utilizando alguna variante de mv source/name_* destination para copiar todo lo que empieza por "nombre_" en el directorio de destino.

EDITAR: Lo anterior se rompe cuando hay espacios en los nombres de los archivos. Una alternativa más complicada que aborda esto sería

ls -d1 [sort options] source/* | tail -n8 | tr '\n' '\0' | xargs --null mv -t destination

aunque sigue haciendo uso del análisis sintáctico ls para obtener una clasificación en cualquier orden que no sea el alfabético.

1voto

xortion Puntos 11

Similar a la sugerencia de t-mager, puedes usar las opciones de ordenación de ls y agarrar los últimos 8 archivos en una lista y estos son tus archivos:

1 10 2 3 4 5 6 7 8 9

utilice el siguiente comando:
for n in `ls|tail -8`; do mv $n ~/temp; done

0voto

tpb261 Puntos 101

También me parece que esto funciona: ls -1 [sort options] | tail -n2 | xargs -I {} -n 1 echo "mv \"{}\" ../t2/"

Por supuesto, hay que eliminar el eco: ls -1 | tail -n2 | xargs -I {} -n 1 mv "{}" ../t2/

El "{}" puede sustituirse por '{}' En realidad, como experimento final, eliminar las comillas (dobles) también funciona. Sorprendente, pero probado.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: