Como localizar e copiar arquivos para a pasta no script bash

1

Na pasta eu tenho arquivos de texto. Eu quero encontrá-los e copie para a pasta criada. Tudo funciona corretamente. O código cria uma pasta e copia arquivos, mas exibe o console:

cp: './02_2017/lks07.txt' and '02_2017/lks07.txt' are the same file

02_2017 é a pasta criada.

Algo está errado no código, mas não sei o que

Este é o código:

date1=$(date '+%Y-%m-%d' -d "-0 month -$(($(date +%d)-1)) days")
date2=$(date '+%Y-%m-%d' -d "-$(date +%d) days +1 month")
date=$(date +'%m_%Y')
mkdir -m 777 $date
find ./ -type f -name '*.txt' -newermt $date1 ! -newermt $date2 -exec cp {} $date \;

Alguém por favor pode me ajudar com isso?

    
por Kamil Sz 19.02.2017 / 09:47

2 respostas

1

Esse problema ocorre porque find procurará arquivos sequencialmente. Por exemplo, considere este layout de diretório:

$ tree
.
├── 02_2017
│   └── foo.txt
└── bar.txt

Quando você executar o comando find , ele encontrará primeiro os arquivos correspondentes no diretório de nível superior, para encontrar bar.txt e movê-lo para 02_2017 . Então, ele irá para 02_2017 e procurará arquivos lá. Existe agora um arquivo 02_2017/bar.txt , então ele tenta copiá-lo para si mesmo, falha e imprime essa mensagem de erro.

Isso não é realmente um problema. Seu script está funcionando bem e está fazendo seu trabalho corretamente. Você pode ignorar com segurança o erro.

Se isso realmente incomoda você, você pode corrigir adicionando -maxdepth 1 ao seu comando find para que ele não caia em subdiretórios:

find ./ -type f -name '*.txt' -newermt $date1 ! -newermt $date2 -exec cp {} $date \;

Ou, melhor ainda, excluindo o diretório de destino do caminho de pesquisa do find:

find ./ -type f -not -path './02_2017/*' -name '*.txt' -newermt $date1 ! -newermt $date2 -exec cp {} $date \;
    
por terdon 19.02.2017 / 13:58
0

Eu tentei realizar a mesma tarefa e recebi o mesmo erro há algum tempo. A ideia era encontrar todos os arquivos que foram modificados recentemente em um período e fazer backup deles separadamente. Apesar de valer a pena mencionar que apesar do erro do cp os arquivos estavam sendo copiados. Ainda não gostei de ter um erro no script então ajustei assim:

find /mnt/net_shares/common/ -type f -mtime -15 >> /tmp/common_mod15.$$.txt

Isso localizará todos os arquivos modificados nos últimos 15 dias e criará uma lista deles em um arquivo de texto. O operador $$ é o ID do processo do script em execução. Isso garante que se eu tiver processos sobrepostos, eles não usarão o mesmo arquivo, tornando-o exclusivo para o ID do processo.

rsync -azv --files-from=/tmp/common_mod15.$$.txt / /mnt/hd2/backups/local/mod15/common/

O segundo passo é usar o rsync em vez de cp. Você pode definir uma lista de texto com a opção --files-from e também comparar arquivos e copiar somente o que foi modificado dos arquivos no meu local de backup. Considerando que cp iria copiar e substituir tudo.

Observe que a barra "extra" em /tmp/common_mod15.$$.txt **/** /mnt... não é um erro de digitação, mas não me lembro exatamente por que precisei. Tinha a ver com o caminho relativo vs absoluto. Dependendo da sua lista gerada, você pode precisar, você pode não. Mas eu vejo que você está trabalhando com caminhos relativos também (./operador) então provavelmente você precisa disso.

Sem dizer que para testá-lo no terminal você precisa se livrar do operador $$ . Só pertence a um script que cria um ID de processo. Lembre-se também de excluir o arquivo criado temporariamente para manter uma pasta /tmp limpa.

    
por Louis Papaloizou 19.02.2017 / 10:44