Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Consider this example (newbie alert):

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

It actually copies file test1, but it returns the message:

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

What am I doing wrong?

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

share|improve this question
add comment

2 Answers 2

up vote 8 down vote accepted

What am I doing wrong?

That's OK. find finds already copied files in new and tries to copy them again, therefore a warning message is displayed.

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

Yes, but you need to modify you command this way:

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

because {} must be at the end of exec statement in this case.

share|improve this answer
    
Works perfect. Thank you. –  Mike May 18 '12 at 13:06
1  
+1 for cp -t. In the example, that warning may be harmless, but Mike said he was really copying thousands of files, so maybe ignoring the errors is a bad idea, because there might be other types of errors that are hard to see. –  Mikel May 18 '12 at 15:19
add comment

Add an echo before the cp and you'll see it's doing

cp new/test1 new
cp test1 new

That's because find doesn't just look in the current directory, it looks in all subdirectories.

Alternatives:

Tell find to not look in subdirectories:

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

Tell find to ignore the new subdirectory:

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

Copy the files into a directory outside of /var/www/import:

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

But if you have subdirectories, you'll end up losing any files that have the same names.

e.g. if you have

test0
test1
scripts/test1

then you'll end up with

test0
test1
new/test1
scripts/test1

which test1 got copied to new?

There's a few ways to handle this, but the easiest and most efficient way I can think of is to use cp --parents

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

that will give you

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

Rush already answered the second part of your question, so I won't repeat him.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.