Mova os arquivos por data para um diretório diferente usando a CLI

9

Tenho um grande número de fotos de um disco rígido antigo que estou tentando organizar. Se eu executar ls -l, percebo que todos esses arquivos têm uma data de criação de 2012 ou antes. Idealmente, gostaria de movê-los para o segundo disco rígido do meu computador, que não está configurado para ser montado automaticamente. De preferência, eu poderia fazer isso tudo como um lote com alguns comandos vinculados. Até agora, eu tenho o ls -l | grep -i 2012que cospe apenas os arquivos com 2012 na data fornecida por ls -l. Agora, o truque seria incluir cptodos esses arquivos no novo diretório. Não sei para onde ir em seguida, porque cada arquivo teria que ser copiado. Qual seria o meu próximo conjunto de comandos?

nerdenador
fonte

Respostas:

13

Não use ls. Não é recomendado usar nesses casos. Além disso, usar greppara filtrar de acordo com a data não é uma boa ideia. O nome do seu arquivo pode conter uma 2012string, mesmo que não tenha sido modificado em 2012.

Use o findcomando e canalize sua saída.

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

Aqui,

-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
fonte
1
Não `-exec mv {} / seu / target / diretório \; ' em vez de '-print 0 | xargs -0 cp -t / your / target / directory 'funciona tão bem quanto a problemas com espaços em nomes? (Além disso, o OP queria mover não copiar )
Hagen von Eitzen
^^ Sim. Ambos alcançam o mesmo objetivo.
Shivams
4

Se você tiver arquivos mais recentes no disco antigo que deseja ignorar, eu continuaria assim

  1. Crie um arquivo de marcador temporário com uma data de modificação que separa os arquivos que eu quero daqueles que não quero
  2. Copiar arquivos mais antigos que o arquivo de marcador para o novo local

Aqui estão exemplos de comandos para isso, que assumem que você deseja manter qualquer hierarquia de diretórios do disco antigo no novo ( cpioé um comando de cópia semelhante tarou 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
fonte
2

Acho que talvez esse problema seja o mesmo que o seu, você também pode verificar isso: Criar subdiretórios e organizar arquivos por data

Escrevo este novo script com base na primeira resposta dessa questão:

for x in *; do
  d=$(date -r "$x" +%Y)
  mkdir -p "/your/new/directory/$d"
  mv -- "$x" "/your/new/directory/$d/"
done
  1. escreva esse script em um arquivo nomeado copy.shem seu diretório antigo.

  2. substitua o /your/new/directorycaminho do seu novo diretório

  3. torne este arquivo executável com chmod +x copy.sh

  4. então execute este arquivo ./copy.sh

warmblue
fonte
1
Você pode querer adicionar um pouco de manipulação de exceção, então o script não mover -se em um 2015diretório.
G-Man diz 'Reinstate Monica'
1

Você provavelmente deve usar uma ferramenta de lote para operações em lote. Isso geralmente implica a leitura / gravação de todos os registros em um único fluxo, em vez de, por exemplo, invocar um cpprocesso separado para cada arquivo copiado.

Já existe uma cpioresposta escrita aqui, a qual, considerando apenas as opções já fornecidas, é provável que eu escolha. No entanto, o cpioformato foi aprimorado e dobrado no paxformato de arquivo padronizado desde o auge. O mesmo vale para tar.

Um POSIX estritamente paxprovavelmente não fornecerá nenhuma opção para filtrar diretamente os membros do arquivo com base nos tempos de modificação do arquivo - embora o padrão especifique o %Tmodificador de formato no modo de lista. Ainda assim, a paximplementação mais comumente conhecida - que é a versão BSD mantida pelo mirabilos - estende isso para um switch CLI diretamente acessível.

Por exemplo, para copiar apenas todos os arquivos na árvore com raiz em ./que foram modificada pela última vez antes ccyymmddHHMMde /target/dirvocê pode fazer:

pax -rwT,201301010000 ./ /target/dir

Para evitar a recorrência em diretórios filhos, faça o seguinte:

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

Veja a manpágina para mais informações.

mikeserv
fonte
Eu acho que eu realmente deveria aprender pax, mas tare cpioainda me ficar bem. +1
roaima
@roaima - estritamente falando, enquanto houver um paxformato de arquivo real (que é uma extensão do formato ustar ) , o pax utilitário especificado para POSIX lê / grava os formatos cpio, pax e ustar. Como todos os três tipos de arquivo são basicamente apenas meios diferentes de codificar os metadados para muitos arquivos, juntamente com os dados reais desses arquivos em um único fluxo, não é muito difícil. Uma vez eu escrevi shitar- que eram apenas algumas linhas de shell-script para - principalmente dd- tardevs de bloco em tempo real com base nas especificações do POSIX.
Mikeerv
Eu gosto do seu script vinculado; estranhamente, teria sido muito útil alguns meses atrás exatamente para o mesmo objetivo. Ah bem. Eu poderia até tentar parar de usar cpio -H ustar...
roaima