¿Cómo mover 30 GB de archivos de una carpeta que contiene 80 GB de archivos?

¿Cómo mover 30 GB de archivos de una carpeta que contiene 80 GB de archivos?

Tengo una carpeta que tiene más de 500 videos y el tamaño de la carpeta es de aproximadamente 80 GB.

Quiero mover 30 GB de videos a otra carpeta, pero ¿cómo?

Estoy usando una terminal y no puedo instalar una GUI.

Respuesta1

No selectivamente (automáticamente)

No conozco ninguna herramienta de línea de comandos que pueda hacer esto... Pero puedes usar un script para mover archivos hasta que se haya movido un cierto tamaño total, por ejemplo, así (Ejecute el script solo una vez... Si lo ejecuta nuevamente, moverá el tamaño especificado nuevamente de los archivos restantes.):

#!/bin/bash

sourc_dir="/path/to/directory" # Set the path to the source directory "no trailing /"
dest_dir="/path/to/directory" # Set the path to the destination directory "no trailing /"
move_size="30" # Set the total size of files to move in Gigabytes
 
# Don't edit below this line
move_size=$(( move_size * 1000000 ))
current_size=$(du -sk "$sourc_dir" | awk '{printf "%d", $1}')
remaining_size=$(( current_size - move_size ))

for f in "$sourc_dir"/*; do
  [ -f "$f" ] || continue
  new_size=$(du -sk "$sourc_dir" | awk '{printf "%d", $1}')
  (( new_size <= remaining_size )) && exit
  mv -n -- "$f" "$dest_dir"/
  done

O incluso una sola línea (no se necesita archivo de script) que puedes ejecutar en la terminal, por ejemplo, así:

for f in /path/to/source/*; do [ -f "$f" ] || continue; (( size >= (30*(1000**3)) )) && break || (( size += $(stat --printf "%s" "$f") ))  && mv -n -- "$f" /path/to/destination/; done

Es posible que desee unset sizepoder volver a ejecutarlo en la misma instancia de Shell.

selectivamente (a mano)

Siempre puede especificar un patrón de shell o tubería desde una herramienta de búsqueda basada en nombres de archivos, tamaños, tipos... etc.

O, más convenientemente, puede utilizar un administrador de archivos basado en consola que admita la selección de múltiples archivos, como por ejemplo el conocido y rico en funciones.Comandante de medianoche GNUque está disponible en los repositorios oficiales de Ubuntu y se puede instalar así:

sudo apt install mc

y para ejecutarlo, escriba mcy presione Enter... Luego se le presentará una interfaz de usuario navegable donde puede usar la Inserttecla del teclado para seleccionar varios archivos... Podrá ver el tamaño total de los archivos seleccionados y su recuento. en tiempo real así:

ingrese la descripción de la imagen aquí

Una vez que haya terminado de seleccionar todos los archivos que desea mover, presione la F6tecla del teclado para abrir el cuadro de diálogo mover/cambiar nombre e ingrese el directorio de destino, luego elija [< OK >]mover los archivos seleccionados a la vez, así:

ingrese la descripción de la imagen aquí

O incluso los menos conocidos y con menos funciones.fff (Administrador de archivos jodidamente rápido):-) ... Esto está curiosamente escrito en bash... Aunque admite la selección de múltiples archivos, es posible que necesites personalizarlo un poco para poder ver el tamaño total de los archivos seleccionados, por ejemplo, como un parche rápido, puedes cambiar la línea 159en el archivo fuente fffde este:

local mark_ui="[${#marked_files[@]}] selected (${file_program[*]}) [p] ->"

a esto:

local mark_ui="[${#marked_files[@]}] $(for f in "${marked_files[@]}"; do (( tsize += $(stat --printf "%s" "$f") )); done; tsize=$((tsize/(1000**2))); printf '[%d M]' "$tsize";) selected (${file_program[*]}) [p] ->"

Entonces simplemente puedes ejecutar ese archivo así (No se necesita instalación):

bash fff

O vea ayuda sobre el uso de esta manera:

bash fff -h

Luego, todo lo que tiene que hacer es simplemente navegar hasta su directorio de origen y comenzar a seleccionar archivos para mover con el m(minúscula) tecla del teclado así:

ingrese la descripción de la imagen aquí

Cuando termine de seleccionar archivos, navegue hasta el directorio de destino y mueva los archivos previamente seleccionados presionando el botón p(minúscula) tecla del teclado.

Respuesta2

Aquí tienes una alternativa arafaLa idea es que no requiere un dudirectorio completo para cada archivo. En lugar de eso, hace un staten cada archivo.una vez, usando find's -printf %spara obtener el tamaño y %pla ruta al archivo que se va a mover.

#!/bin/bash

src='foo'
dest='bar'

# 30GB in bytes to move:
(( bytestomove=30*(1000**3) ))
movedbytes=0

while IFS=$'\t' read -r -d '' bytes file
do
    # if we already moved enough, break out
    (( movedbytes >= bytestomove )) && break;

    # try to move it, break out if it fails
    mv -n -- "$file" "$dest" || break

    # successfully moved, add bytes to movedbytes
    (( movedbytes += bytes ))
done < <(find "$src" -type f -printf "%s\t%p\0")

(( movedmegs=movedbytes/(1000**2) ))
printf "Moved %d MB\n" $movedmegs

Respuesta3

@TedLyngmo señaló que la solución tar que presenté por primera vez copia efectivamente los archivos y no los mueve. Esta distinción es importante por 2 razones:

  1. Con una copia, los archivos de origen permanecen, mientras que con un movimiento, los archivos de origen ya no existen en sus ubicaciones de origen.
  2. Si los archivos se mueven dentro del mismo sistema de archivos, como también puede ser el caso en esta pregunta, mvsimplemente se volverá a vincular el archivo fuente a la nueva ubicación y no se copiará el contenido en absoluto. Por lo general, esto será significativamente más rápido que copiar, especialmente para archivos grandes.

Escenario de movimiento

Todavía podemos usar los tarconceptos del escenario de copia proporcionado originalmente para crear una lista de archivos que contenga solo los primeros 30 GB de archivos que tarse encuentren y luego mover solo esos archivos:

#!/bin/bash

# Convert human-readable number, e.g. 1M, 30G to number of 1024 byte blocks 
limit=$(numfmt --from=auto $1 --to-unit 1024)
src_dir=$2
dest_dir=$3

mkdir $dest_dir
filelist=$(readlink -f $(mktemp -p $dest_dir))

# create a list of files to be moved.  tar -v outputs filenames to stdout, and 
# the dest archive is /dev/null
tar -v -L $limit -F false -c -f /dev/null -C $src_dir . > $filelist 2> /dev/null
tar_result=$?
if [ "$tar_result" = 2 ]; then
    echo "$1 limit was hit - some unmoved files will remain in $dest_dir"
else
    echo "All files will be moved"
fi

pushd $dest_dir > /dev/null
abs_dest_dir=$PWD
# create directories in the destination
grep '/.*/$' $filelist | xargs mkdir -p
popd > /dev/null

pushd $src_dir > /dev/null
# create hard links in the destination
grep -v '/$' $filelist | xargs cp -l --parents -t $abs_dest_dir
# unlink source files
grep -v '/$' $filelist | xargs rm
# remove source directories in reverse order, if they are empty
grep '/.*/$' $filelist | tac | xargs rmdir --ignore-fail-on-non-empty
popd > /dev/null

rm $filelist

Esto es más complejo de lo que me gustaría:

  • mvno ofrece tanto control de las rutas de origen y destino para múltiples archivos (específicamente no hay un análogo de la cpopción --parents), por lo que los movimientos de archivos se logran creando enlaces físicos en las ubicaciones de destino y luego desvinculando los archivos de origen.

  • Debido a que los directorios de origen contienen una combinación de entradas que se deben mover y que no, los directorios se deben volver a crear en el destino y no simplemente moverlos (junto con todo el contenido). Por lo tanto, los directorios de destino apropiados se crean antes de mover los archivos y los directorios de origen correspondientes se eliminan después de mover los archivos, si están vacíos.

Advertencias

  • tar -vgenerará una entrada de archivo por línea. Esto fallará espectacularmente si hay caracteres especiales en los nombres de las rutas, por ejemplo, nuevas líneas. Esperemos que los nombres de las rutas de origen tengan nombres sensatos.

  • Esto moverá un poco menos de 30 GB de datos de archivos reales, ya que la transmisión contiene metadatos (nombres de archivos, marcas de tiempo, etc.), así como el contenido real, y todo esto está sujeto al límite de 30 GB.

  • Estoy jugando un poco rápido y relajado con KB versus kb aquí. Dado que el -Lparámetro funciona en unidades de 1024 bytes, esto en realidad limita el movimiento a 3.072.000.000 bytes de flujo tar. Ajuste los números según corresponda.

  • filelist.txt se crea en el directorio actual. Se requerirán permisos de escritura para esto, esto probablemente sea un hecho, ya que las operaciones de movimiento requerirán permisos de escritura de todos modos.

Copiar escenario

Puede utilizar tarpara convertir su carpeta en una secuencia y luego tarvolver a convertir la secuencia en archivos en una nueva ubicación. El primero tarutiliza -Lpara limitar la "longitud de la cinta" a 3000000 KB, antes de solicitar una nueva cinta. tarusa -F para ejecutarse falsedespués de cada "cinta". Debido a que falsedevuelve un error, la transferencia se detiene después de la primera "cinta", es decir, 30 GB. Hacer que todos los datos pasen por solo 2 invocaciones de tar debería ser más rápido que recorrer todos los archivos con bucles bash.

mkdir dest.dir
tar -cv -L 3000000 -F false -C src.dir . | tar -x -C dest.dir/

Esto copiará los archivos hasta alcanzar el límite de 30 GB, luego el tarcorreo electrónico generará un error con:

tar: Unexpected EOF in archive
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now
tar: ‘false’ command failed
tar: Error is not recoverable: exiting now

tarno transferirá el archivo que se estaba transfiriendo cuando se alcanzó el límite; no se escribirá en el destino en absoluto.

Advertencias

  • Esto copiará un poco menos de 30 GB de datos de archivos reales, ya que la transmisión contiene metadatos (nombres de archivos, marcas de tiempo, etc.), así como el contenido real, y todo esto está sujeto al límite de 30 GB.

  • Estoy jugando un poco rápido y relajado con KB versus kb aquí. Dado que el -Lparámetro funciona en unidades de 1024 bytes, esto en realidad limita la transferencia a 3.072.000.000 bytes de flujo tar. Ajuste los números según corresponda.


Las ediciones anteriores de esta respuesta usaron find-cpio-head-cpio y luego tar-head-tar. La solución tar-tar que se presenta ahora debería ser suficiente, pero inspeccione el historial de edición si las otras soluciones son de interés.

Respuesta4

Vaya a la carpeta donde están sus archivos:

cd SOURCE_FOLDER

hacer una lista de archivos en esa carpeta

ls > list.txt

Edítalo en cualquier editor y elimina los archivos que NO quieras mover. Guarde el resultado para que ahora list.txt tenga solo los archivos que desea mover. Ahora ejecute este script simple que lee cada línea de su archivo list.txt y mueve ese archivo a su directorio de destino.

while IFS= read -r line; do mv "$line" ../DESTINATION_DIRECTORY/"$line"; done < list.txt

información relacionada