9

I copied a directory using this:

cp -r dir/ ../../

without thinking and realized that it copied the contents of dir instead of actually dir to the above directory. Now I have a mess of files I need to delete so I can redo the cp correctly. How can I delete all the files that I mistakenly copied over if they don't match anything in particular?

1

4 Answers 4

12

Ok, this is basically the same as klapaucius' answer. (And it won't repair any damage done if cp has overwritten some existing files.)

Assuming you are in the source directory (in dir). This command:

find . -type f -exec echo '{}' ';'

will list all the files (recursively) present in your dir directory (quite like -print). The -type f option is there to prevent the listing of sub-directories.

So, if you use:

find dir -type f -exec echo '../../../{}' ';'

This should list corresponding files (copies) in the target directory.

Now if the list is correct, you will be able to remove the copies using:

find dir -type f -exec rm -- '../../../{}' ';'

As for pruning remaining empty directories that come from the cp… hum…

9
  • I'm using the echo method to double check the file names first. However, I need to change dir to . or else it doesn't seem to work. Also, it only lists the files in dir, not the ones also in ../..
    – nopcorn
    Aug 31, 2011 at 13:11
  • Ah yes, I got confused by your description. Why did cp copy the content and not the directory in this case? Aug 31, 2011 at 13:16
  • 1
    Ah! that's cause of the final /! Aug 31, 2011 at 13:24
  • 1
    The one in ./dir/? Should it have been ./dir instead?
    – nopcorn
    Aug 31, 2011 at 13:27
  • 1
    Yes, but this happens only with some cp versions it seems… Mine (coreutils 8.12) has not this behavior anymore. (It was useful sometimes.) Aug 31, 2011 at 13:31
2

Use find in combination with -exec. Better test with ls before like this:

find . -name "*" -exec ls ../../{} \;
5
  • What exactly is this doing? For every file in . (the copied dir), it sees if it is also two directories up? To remove them I use rm instead of ls?
    – nopcorn
    Aug 31, 2011 at 12:24
  • Yes, exactly. Sorry, forgot to explain it
    – klapaucius
    Aug 31, 2011 at 12:34
  • Dont worry about it, I'll test this first before trying it on my server :)
    – nopcorn
    Aug 31, 2011 at 12:41
  • I get find: missing argument to '-exec'
    – nopcorn
    Aug 31, 2011 at 12:45
  • Do you have a blank between {} and \; ?
    – klapaucius
    Aug 31, 2011 at 12:57
1

The following code handles file names which contain embedded newlines I've put a full version script on paste.ubuntu. It checks for existance and matching sizes... The code to generate the test data is also included there.

# This lists the original fully-qualified filename, 
# and its would-be counterpart (assuming it exists) 
unset a i
while IFS= read -r -d $'\0' relf; do
    printf "%s\n$s" "$PWD${relf:1}" "$(dirname "$(dirname "$PWD")")${relf:1}"
done < <(find  . -type f  \! -name '.' -name '*' -print0)

Here is a sample output of the full version (mentioned above), where one file is missing, and another has a different file size to the original

WARNING -----
NOT in target   ./file1
ok --------
sizes match     ./c/file4-in-subdir
WARNING ------
size mis-match  ./file3   is   triple-spaced
ok --------
sizes match     ./file2
has newline!
-2

You want to remove into PATH_DIR1 existing files in PATH_DIR2 :

find PATH_DIR1 -type f  -exec basename '{}' ';' | xargs printf -- 'PATH_DIR2/%s\n' | xargs rm

Explanations :

  1. List all filenames in PATH_DIR1

find PATH_DIR1 -type f -exec basename '{}' ';'

  1. Filter the previous listing with the existing files in PATH_DIR2 (find the intersect data)

xargs printf -- 'PATH_DIR2/%s\n'

  1. Execute the remove action to the filtered result

xargs rm

1
  • 1
    Would you mind describing the various steps of your pipeline while also mentioning any restrictions or pitfalls (filenames containing spaces may be an issue, for example)? Are you deliberately skipping over directories?
    – Kusalananda
    Nov 11, 2023 at 6:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .