Sposta i file per data in un'altra directory usando l'interfaccia della riga di comando


9

Ho un gran numero di foto da un vecchio disco rigido che sto cercando di organizzare. Se corro ls -l, noto che tutti questi file hanno una data di creazione del 2012 o precedente. Idealmente, vorrei spostarli sul secondo disco rigido del mio computer, che non è impostato per il montaggio automatico. Preferibilmente, potrei fare tutto questo in gruppo con alcuni comandi collegati tra loro. Finora, ho ls -l | grep -i 2012che sputa solo i file con il 2012 nella data fornita da ls -l. Ora, il trucco sarebbe cpinglobare tutti quei file nella nuova directory. Non sono sicuro dove andare dopo con questo perché ogni file dovrebbe essere copiato. Quale sarebbe il mio prossimo set di comandi?

Risposte:


13

Non usare ls. Non è raccomandato l'uso in questi casi. Inoltre, utilizzare grepper filtrare in base alla data non è una buona idea. Il nome file potrebbe contenere 2012stringa, anche se non è stato modificato nel 2012.

Usa il findcomando e convoglia il suo output.

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

Qui,

-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 

1
Non `-exec mv {} / your / target / directory \; ' invece di '-print 0 | xargs -0 cp -t / your / target / directory 'funziona altrettanto bene per quanto riguarda i problemi con gli spazi nei nomi? (Inoltre, l'OP voleva spostare non copiare )
Hagen von Eitzen,

^^ Sì. Entrambi raggiungono lo stesso obiettivo.
Shivams,

4

Se hai dei file più recenti sul vecchio disco che vuoi ignorare, lo farei in questo modo

  1. Crea un file marker temporaneo con una data di scadenza modificata che separa i file che desidero da quelli che non preferisco
  2. Copia i file più vecchi del file marker nella nuova posizione

Ecco alcuni comandi di esempio per questo, che presuppongono che tu voglia mantenere qualsiasi gerarchia di directory dal vecchio disco nel nuovo ( cpioè un comando di copia, simile 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

2

Penso che forse questo problema sia molto simile al tuo, puoi anche verificarlo: crea sottodirectory e organizza i file per data

Scrivo questo nuovo script basato sulla prima risposta di quel problema:

for x in *; do
  d=$(date -r "$x" +%Y)
  mkdir -p "/your/new/directory/$d"
  mv -- "$x" "/your/new/directory/$d/"
done
  1. scrivi questo script in un file chiamato copy.shnella tua vecchia directory.

  2. sostituisci /your/new/directorycon il percorso della tua nuova directory

  3. rendere questo file eseguibile con chmod +x copy.sh

  4. quindi eseguire questo file con ./copy.sh


1
Si potrebbe desiderare di aggiungere un po 'la gestione delle eccezioni, quindi lo script non si muove se stessa in una 2015directory.
G-Man dice "Reinstate Monica"

1

Probabilmente dovresti usare uno strumento batch per le operazioni batch. Ciò comporta in genere la lettura / scrittura di tutti i record in un singolo flusso anziché, ad esempio, l'invocazione di un cpprocesso separato per ciascun file copiato.

C'è già una cpiorisposta scritta qui, che, date solo le opzioni già fornite, è probabilmente ciò che sceglierei. Tuttavia, il cpioformato è stato migliorato e ripiegato nel paxformato di archivio standardizzato sin dai suoi tempi d'oro. Lo stesso vale per tar.

Un POSIX rigoroso paxnon fornirà probabilmente alcuna opzione per filtrare direttamente i membri dell'archivio in base ai tempi di modifica dei file, sebbene lo standard specifichi il %Tmodificatore di formato in modalità elenco. Tuttavia, l' paximplementazione più comunemente disponibile che conosco - che è la versione BSD gestita da mirabilos - la estende in uno switch CLI direttamente accessibile.

Ad esempio, per copiare solo tutti i file nella struttura di radice in ./cui sono stati modificati prima ccyymmddHHMMdi /target/dirche si possa fare:

pax -rwT,201301010000 ./ /target/dir

Per evitare di ricorrere in directory secondarie, è possibile invece:

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

Vedi la manpagina per di più.


Immagino che dovrei davvero imparare pax, ma tare cpiocomunque mi sopporto bene. +1
roaima,

@roaima: a rigor di termini, mentre esiste un paxformato di archivio effettivo (che è un'estensione del formato ustar ) , l' pax utilità specificata da POSIX legge / scrive i formati cpio, pax e ustar. Poiché tutti e tre i tipi di archivio equivalgono principalmente a diversi modi di codificare i metadati per molti file insieme ai dati effettivi di detti file in un singolo flusso, non è davvero troppo lungo. Una volta ho scritto shitar- che era solo alcune righe di shell-script per - principalmente dd- sviluppatori di tarblocchi al volo in base alle specifiche POSIX.
Mikeserv,

Mi piace il tuo script collegato; stranamente sarebbe stato molto utile un paio di mesi fa esattamente per lo stesso scopo. Oh bene. Potrei anche provare a smettere di usare cpio -H ustar...
roaima,
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.