Come si spostano i file in blocco in una directory in modo sicuro?


10

Come posso spostare i file in una directory dove potrebbero esserci centinaia o migliaia di file nella directory e potresti non essere sicuro che ci siano duplicati ... Quale metodo useresti?

Il modo in cui gestire i duplicati varierà, a volte sovrascriveremo, a volte dobbiamo essere più sicuri. L'IO può essere importante perché si tratta di server di produzione. Ma data la quantità un prompt per i file non duplicati non è un'opzione. La conservazione delle autorizzazioni, i timestamp, ecc., È importante. Di solito non sappiamo quali siano i dati.

Oh, e non mvè necessario l' utilizzo rsync, cpsoluzioni benvenute.

nota: stiamo eseguendo CentOS 5.5, quindi fatemi sapere se non funzionerà lì perché è una funzione più recente ...


Cosa vorresti fare per i duplicati?

@Iain dipende dalla situazione? Lavoro in un host web ... dipende molto dal mve se ci teniamo alla conservazione nel caso di ... e se abbiamo già fatto un backup. Questa domanda è abbastanza aperta. Sto solo cercando buone opzioni e forse un commento sul fatto che possa mordere o meno e come.
xenoterracide,

Presumo che ci siano troppi file che la shell può gestire mv * ../o mv -i * ../?
Michael Mrozek

@Michael Sono sicuro che varia ... in alcuni casi probabilmente no. In alcuni casi forse. Sto cercando di catturare quante più opzioni possibili per il mio ambiente di lavoro.
xenoterracide,

Risposte:


6

Consiglierei di usare rsync dal genitore:

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

che eseguirà il backup di tutti i file duplicati esistenti nel genitore nel file -originale.


Penso che -aimplichi-r
xenoterracide il

@xenoterracide - Right you 'r'
Tok

@Tok è possibile fare la copia come hardlink? per non sprecare IO. (come -lper cp)
xenoterracide,

@xenoterracide: è possibile utilizzare i flag -Ho --hard-linksper rsync per conservare i collegamenti reali .
Tok

1
@xenoterracide - È possibile utilizzare il --link-dest=DIRflag per ottenere questo comportamento come: rsync -avP --link-dest=/path/to/src /path/to/src/* /path/to/dest/che collegherà duramente in dst / qualsiasi file invariato tra src e src, in questo caso tutti i file. Normalmente vedi questo flag usato quando desideri ricollegare i file di backup senza copiare i loro dati come --link-dest=/most/recent/backup.
Tok

4
cp -bal . ..

Questo copierà tutto nella directory corrente nella directory sopra di essa, mantenendo tutte le autorizzazioni, usando hardlink per minimizzare IO se possibile, e sui duplicati crea il nome del file ~

dopo di che

rm -rf . ; cd .. ; rmdir <originaldir>;

probabilmente si imbatte in un gran numero di problemi con i file ... ma non è intensivo per IO come rsync.
xenoterracide,

2

In questo esempio verranno spostati i file da '/ parent / old-dir' a '/ parent':

cd /parent

rsync -av --progress old-dir/ .

rm -rf old-dir

Con le regole rsync sostituirà i duplicati con file più recenti da old-dir.


1

Puoi provare

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

che sovrascriverà i file duplicati in ..

È possibile utilizzare mv -u '{}' per non sovrascrivere se il duplicato in .. è uguale o più recente


perché pipe trova su xargs? perché non usare +
xenoterracide il

1
@xenoterracide - Abitudine e portabilità (è un'estensione GNU). Inoltre, l'ho appena provato e non riesco a capire come passare il secondo parametro ..al mv '{}' +comando poiché il + si aggiunge alla fine.

@Iain il + è in POSIX Mi è stato effettivamente detto in precedenza GNU find era in ritardo per ottenerlo.
xenoterracide,

Hai ragione ma non riesco ancora a immaginare un modo per usare il ..

2
@xenoterracide: Con coreutils GNU: -exec mv -t .. -- {} +. Portabile: -exec sh -c 'mv -- "$@"' _ {} +.
Gilles 'SO- smetti di essere malvagio' il

1

mv -i richiede solo se la destinazione esiste.

yes n | mv -i …sposta tutti i file che non esistono nella directory di destinazione. Su FreeBSD e OSX, puoi accorciarlo a mv -n ….

Si noti che nessuno di questi unirà un argomento di directory con una directory esistente con lo stesso nome nella directory di destinazione.


Un problema a parte è come agire su tutti i file nella directory corrente. Esistono due problemi: afferrare tutti i file ( *omette i file punto) e non eseguire in una riga di comando. Su Linux (o più in generale con GNU find e GNU coreutils):

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

Con GNU trova ma non coreutils GNU (o coreutils GNU precedenti):

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

portabile:

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

Come al solito, zsh semplifica le cose. Non ha una limitazione della lunghezza della riga di comando internamente, quindi se usi il suo mvbuiltin non devi preoccuparti di questo. E puoi dire di non ignorare i file punto con il Dqualificatore glob. Limitazione: non funziona su tutti i filesystem (da zsh 4.3.10).

zmodload zsh/files
mv -i -- *(D) ..

a molti argomenti?
xenoterracide,

0

Ho detto sul nostro ML

mv * ..

ovviamente questo non è molto sicuro ... sovrascriverà le cose. Potrebbe avere dei limiti che non ho mai incontrato.


2
Se hai un gran numero di file probabilmente otterrai un "errore dell'elenco argomenti troppo lungo".

2
Potrebbe fare cose cattive se hai un nome file che inizia con -. Non rileverà i file il cui nome inizia con ..
Gilles 'SO- smetti di essere cattivo' il

0

Quello che segue è un modello Python che ho usato con buoni risultati in passato.

#!/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")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.