issue com find -exec cp

4

Considere este exemplo:

touch test0
touch timestamp
touch test1
sudo find /var/www/import -iname 'test*' -newer timestamp -exec cp {} new \;

Na verdade, ele copia o arquivo test1, mas retorna a mensagem:

cp: '/var/www/import/new/test1' and 'new/test1' are the same file

O que estou fazendo de errado?

2ª pergunta, posso usar "+" com este comando para que os arquivos sejam copiados em um único "pacote"? Existem milhares de arquivos!

    
por Mike 18.05.2012 / 13:28

2 respostas

11

What am I doing wrong?

Tudo bem. find encontra os arquivos já copiados em new e tenta copiá-los novamente, portanto, uma mensagem de aviso é exibida.

can I use "+" with this command so that files are copied in a single "bundle"? There are thousands of files!

Sim, mas você precisa modificar seu comando dessa maneira:

find /var/www/import -iname 'test*' -newer timestamp -exec cp -t new {} +

porque {} deve estar no final da instrução exec neste caso.

    
por 18.05.2012 / 13:51
4

Adicione um echo antes do cp e você verá que está fazendo

cp new/test1 new
cp test1 new

Isso porque find não procura apenas no diretório atual, mas em todos os subdiretórios.

Alternativas:

Diga find para não procurar em subdiretórios:

find /var/www/import -maxdepth 1 \
    -iname 'test*' -newer timestamp -exec cp {} new \;

Diga a find para ignorar o subdiretório new :

find /var/www/import -type d -name new -prune -o \
    -iname 'test*' -newer timestamp -exec cp {} new \;

Copie os arquivos para um diretório fora de /var/www/import :

find /var/www/import \
    -iname 'test*' -newer timestamp -exec cp {} /var/www/import.new \;

Mas se você tiver subdiretórios, acabará perdendo arquivos com os mesmos nomes.

por exemplo. se você tiver

test0
test1
scripts/test1

você acabará com

test0
test1
new/test1
scripts/test1

qual test1 foi copiado para new ?

Existem algumas maneiras de lidar com isso, mas a maneira mais fácil e eficiente de usar é usar cp --parents

cd /var/www/import
find . -type d -name new -prune -o \
    -type f -iname 'test*' -newer timestamp -exec cp --parents {} new \;

que lhe dará

test0
test1
new/test1
new/scripts/test1
scripts/test1

O Rush já respondeu à segunda parte da sua pergunta, por isso não vou repeti-lo.

    
por 18.05.2012 / 17:17

Tags