¿Cómo mover masivamente los archivos hacia arriba de un directorio de forma segura?

10

¿Cómo puedo mover archivos hacia arriba en un directorio donde puede haber cientos o miles de archivos en el directorio, y es posible que no esté seguro de si hay engaños ..? ¿Qué método usarías?

La forma de manejar los engaños variará, a veces sobrescribiremos, a veces necesitamos estar más seguros. IO puede ser importante porque estos son servidores de producción. Pero dada la cantidad, una solicitud de archivos no duplicados no es una opción. La preservación de los permisos y las marcas de tiempo, etc., es importante. Por lo general, no sabremos cuáles son los datos.

Ah, y su uso mvno es obligatorio rsync, las cpsoluciones son bienvenidas.

nota: estamos ejecutando CentOS 5.5, así que avíseme si no funcionará allí debido a que es una característica más reciente ...

xenoterracida
fuente
¿Qué querrías hacer con los engañados?
@Iain depende de la situación? Trabajo en un servidor web ... realmente depende de mvsi nos preocupa la preservación en el caso de ... y si ya hemos hecho una copia de seguridad. Esta pregunta es bastante abierta. Solo estoy buscando buenas opciones, y tal vez un comentario sobre si puede morderte o no y cómo.
xenoterracide
¿Supongo que hay demasiados archivos para que el shell los maneje mv * ../o mv -i * ../?
Michael Mrozek
@Michael Estoy seguro de que varía ... en algunos casos, probablemente no. En algunos casos tal vez. Estoy tratando de atrapar tantas opciones para mi entorno de trabajo como sea posible.
xenoterracide

Respuestas:

6

Recomendaría usar rsync del padre:

rsync -avPr -b --suffix='-original' child/* .

que hará una copia de seguridad de todos los archivos duplicados existentes en padre a archivo original .

Tok
fuente
Creo que -aimplica-r
xenoterracide
@xenoterracide - Correcto 'r'
Tok
@ Tomó, ¿es posible hacer las copias como enlaces duros? para no desperdiciar IO. (como -lpara cp)
xenoterracide
@xenoterracide: puede usar las banderas -Ho --hard-linkspara rsync para preservar los enlaces duros.
Tok
1
@xenoterracide: puede usar el --link-dest=DIRindicador para lograr este comportamiento como: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/que se vinculará en dst / cualquier archivo sin cambios entre src y src, en este caso todos los archivos. Por lo general, ve este indicador utilizado cuando desea volver a vincular archivos de copia de seguridad sin copiar sus datos como --link-dest=/most/recent/backup.
Tok
4
cp -bal . ..

Esto copiará todo en el directorio actual al directorio que se encuentra sobre él, conservando todos los permisos, utilizando enlaces duros para minimizar IO si es posible, y en duplicados crea un nombre de archivo ~

después de esto

rm -rf . ; cd .. ; rmdir <originaldir>;
xenoterracida
fuente
probablemente se encuentra con la gran cantidad de problemas de archivos ... pero no es IO intensivo como rsync.
xenoterracide
2

En este ejemplo, moverá los archivos de '/ parent / old-dir' a '/ parent':

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

Por reglas rsync reemplazará dups con archivos más nuevos de old-dir.

Alexander Pogrebnyak
fuente
1

Puedes probar

find . -maxdepth 1 -print0 | xargs -I '{}' -r0 mv '{}' ..

que sobrescribirá los archivos duplicados en ...

Puede usar mv -u '{}' para no sobrescribir si el engaño en ... es el mismo o más nuevo


fuente
¿Por qué pipa encontrar a xargs? por qué no usar +
xenoterracide
1
@xenoterracide - Hábito y portabilidad (es una extensión de GNU). Además de eso, lo he intentado y no puedo entender cómo pasar el segundo parámetro ..al mv '{}' +comando, ya que el + simplemente se agrega al final.
@Iain el + está en POSIX En realidad me dijeron que GNU find era tarde para obtenerlo.
xenoterracide
Tienes razón, pero todavía no puedo encontrar una manera de usar el ..
2
@xenoterracide: Con GNU coreutils: -exec mv -t .. -- {} +. Portable: -exec sh -c 'mv -- "$@"' _ {} +.
Gilles 'SO- deja de ser malvado'
1

mv -i solo pregunta si el destino existe.

yes n | mv -i …mueve todos los archivos que no existen en el directorio de destino. En FreeBSD y OSX, puede acortar esto mv -n ….

Tenga en cuenta que ninguno de estos combinará un argumento de directorio con un directorio existente con el mismo nombre en el directorio de destino.


Otro tema es cómo actuar sobre todos los archivos en el directorio actual. Hay dos problemas: tomar todos los archivos ( *omite los archivos de puntos) y no encontrarse con una línea de comando. En Linux (o más generalmente con GNU find y GNU coreutils):

find . -mindepth 1 -maxdepth 1 -exec mv -i -t .. -- {} +

Con GNU encuentra pero no GNU coreutils (o GNU coreutils anteriores):

find . -mindepth 1 -maxdepth 1 -exec sh -c 'mv -i -- "$@" "$0"' .. {} +

Portablemente:

find . -name . -o -exec sh -c 'mv -i -- "$@" "$0"' .. {} -type d -prune

Como de costumbre, zsh facilita las cosas. No tiene una limitación de longitud de línea de comando internamente, por lo que si usa su mvincorporado no necesita preocuparse por eso. Y puede decirle que no ignore los archivos de puntos con el Dcalificador glob. Limitación: esto no funciona en los sistemas de archivos (a partir de zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..
Gilles 'SO- deja de ser malvado'
fuente
a muchos argumentos?
xenoterracide
0

Dije en nuestro ML

mv * ..

obviamente esto no es muy seguro ... sobrescribirá las cosas. Puede tener límites con los que nunca me he encontrado.

xenoterracida
fuente
2
Si tiene una gran cantidad de archivos, es probable que obtenga un "error de lista de argumentos demasiado largo".
2
Puede hacer cosas malas si tiene un nombre de archivo que comienza con -. No capturará archivos cuyo nombre comience con ..
Gilles 'SO- deja de ser malvado'
0

La siguiente es una plantilla de Python que he usado con buenos resultados en el pasado.

#!/usr/bin/env python
#
# Bart Kastermans, www.bartk.nl
#
# rename of collection of files in a directory
import os
import shutil

# only work on files whose name starts with a D
files = [filename for filename in os.listdir ("/Users/kasterma/Music/Audio Hijack/") if filename[0] =="D"]

for filename in files:
    shutil.move (filename, filename [:23] + ".mp3")
kasterma
fuente