Mover archivos por fecha a un directorio diferente usando CLI

9

Tengo una gran cantidad de imágenes de un disco duro viejo que estoy tratando de organizar. Si ejecuto ls -l, noto que todos estos archivos tienen una fecha de creación de 2012 o anterior. Idealmente, me gustaría moverlos al segundo disco duro de mi computadora, que no está configurado para montarse automáticamente. Preferiblemente, podría hacer todo esto como un lote con algunos comandos vinculados entre sí. Hasta ahora, tengo ls -l | grep -i 2012que escupe solo los archivos con 2012 en la fecha proporcionada por ls -l. Ahora, el truco sería llevar cptodos esos archivos al nuevo directorio. No estoy seguro de dónde ir después con esto porque cada archivo tendría que copiarse. ¿Cuál sería mi próximo conjunto de comandos?

nerdenator
fuente

Respuestas:

13

No utilice ls. No se recomienda su uso en tales casos. Además, usar greppara filtrar según la fecha no es una buena idea. Su nombre de archivo puede contener una 2012cadena, aunque no se modificó en 2012.

Use el findcomando y canalice su salida.

find . -newermt 20120101 -not -newermt 20130101 -print0 | xargs -0 cp -t /your/target/directory 

Aquí,

-newermt 20120101  ==>  File's modified date should be newer than 01 Jan 2012
-not               ==>  reverses the following condition. Hence file should be older than 01 Jan 2013
-print0 and -0     ==>  Use this options so that the command doesn't fail when filenames contain spaces 
shivams
fuente
1
No `-exec mv {} / your / target / directory \; ' en lugar de '-print 0 | xargs -0 cp -t / your / target / directory '¿funciona igual de bien con respecto a problemas con espacios en los nombres? (Además, el OP quería moverse, no copiar )
Hagen von Eitzen
^^ Sí Ambos logran el mismo objetivo.
shivams
4

Si tiene archivos más nuevos en el disco antiguo que desea ignorar, lo haría de esta manera

  1. Cree un archivo de marcador temporal con una fecha de modificación que separe los archivos que quiero de los que no
  2. Copie archivos anteriores al archivo marcador en la nueva ubicación

Aquí hay ejemplos de comandos para esto, que suponen que desea mantener cualquier jerarquía de directorios del disco anterior en el nuevo ( cpioes un comando de copia, similar a taro pax):

touch -t 201201010000 /tmp/marker    # YYYYMMDDhhmm == Jan 1st, 2012
cd /path/to/old/disk
find . -type f \! -newer /tmp/marker -print0 | cpio -pmd0 /path/to/new/disk
roaima
fuente
2

Creo que este problema es muy similar al tuyo, también puedes consultarlo: crea subdirectorios y organiza los archivos por fecha

Escribo este nuevo script basado en la primera respuesta de ese problema:

for x in *; do
  d=$(date -r "$x" +%Y)
  mkdir -p "/your/new/directory/$d"
  mv -- "$x" "/your/new/directory/$d/"
done
  1. escriba este script en un archivo nombrado copy.shen su directorio anterior.

  2. reemplace el /your/new/directorycon la ruta de su nuevo directorio

  3. hacer que este archivo sea ejecutable con chmod +x copy.sh

  4. luego ejecute este archivo por ./copy.sh

Warmblue
fuente
1
Es posible que desee agregar algo de manejo de excepciones, para que el script no se mueva solo a un 2015directorio.
G-Man dice 'Restablecer a Monica'
1

Probablemente debería usar una herramienta por lotes para las operaciones por lotes. Hacerlo generalmente implicará leer / escribir todos los registros en una sola secuencia en lugar de, por ejemplo, invocar un cpproceso separado para cada archivo copiado.

Ya hay una cpiorespuesta escrita aquí, que, dada solo las opciones que ya le proporcioné, es probable que yo elija. Sin embargo, el cpioformato se ha mejorado y plegado en el paxformato de archivo estandarizado desde su apogeo. Lo mismo es cierto de tar.

Un POSIX estricto paxprobablemente no proporcionará ninguna opción para filtrar directamente a los miembros del archivo en función de los tiempos de modificación del archivo, aunque el estándar especifica el %Tmodificador de formato del modo de lista. Aún así, la paximplementación más comúnmente disponible que conozco, que es la versión BSD mantenida por mirabilos , lo extiende a un interruptor CLI directamente accesible.

Por ejemplo, para copiar todos los archivos sólo en el árbol de raíz en ./que fueron modificada por última vez antes de ccyymmddHHMMque /target/dirse podía hacer:

pax -rwT,201301010000 ./ /target/dir

Para evitar recurrir a directorios secundarios, puede hacer lo siguiente:

pax -rwdT,201301010000 ./* /target/dir

Vea la manpágina para más.

mikeserv
fuente
Creo que realmente debería aprender pax, pero tary cpiotodavía me quedo así. +1
roaima
@roaima: estrictamente hablando, aunque hay un paxformato de archivo real (que es una extensión del formato ustar ) , la pax utilidad especificada por POSIX lee / escribe cpio, pax y formatos ustar. Debido a que los tres tipos de archivo consisten principalmente en diferentes medios para codificar los metadatos de muchos archivos junto con los datos reales de dichos archivos en una sola secuencia, en realidad no es demasiado difícil. Una vez escribí shitar- que era sólo unas pocas líneas de shell-script para - en su mayoría dd- taring desarrolladores de bloques sobre la marcha basado en la especificación POSIX.
mikeserv
Me gusta tu guión vinculado; Curiosamente, habría sido muy útil hace un par de meses exactamente para ese mismo propósito. Oh bien. Incluso podría intentar dejar de usar cpio -H ustar...
roaima