1

Im using the find command to find common files between two directories:

find  "$SOURCE" "$TARGET" -printf "$TARGET%P\n" | sort | uniq -d

problem is it always outputs an empty line on the top. Due to that when I try to delete the common files from the source like this:

find  "$SOURCE" "$TARGET" -printf "$TARGET%P\n" | sort | uniq -d | xargs rm

I get error:

rm: cannot remove ‘/target/directory/path’: Is a directory

How top get rid of the extra line

1
  • Add ! -type d before the -printf to suppress printing the directory.
    – meuh
    Jul 4, 2017 at 16:04

4 Answers 4

2

You should avoid using xargs rm here since that results in, essentailly, parsing the output of ls, which is a classic antipattern.

Instead, you could do something like:

for tgt in "$TARGET"/*; do
    if [[ -e "$SOURCE/${tgt##*/}" ]]; then
        rm "$tgt"
    fi
done

of course, that won't recurse, so if you wanted that you can use find like so:

find "$TARGET" -type f -exec bash -c 'if [ -e "${1//$TARGET/$SOURCE}" ]; then rm "$1"; fi' "" {} \;

or apparently there's a tool called fdupes that sounds like it might do the job for you

2
  • just wondering, if I have lots of files in my target will using find be faster? Jul 7, 2017 at 14:21
  • You'd have to profile to be sure, but my gut here is that the for loop would be faster since the find will have to spawn a shell to do the existence test for each file Jul 7, 2017 at 14:22
1

Quick and dirty -> add tail -n +1 leading to find "$SOURCE" "$TARGET" -printf "$TARGET%P\n" | tail -n +1 | sort | uniq -d | xargs rm

1
  • You cold also avoid the top folder leading to the empty line find "$SOURCE" -mindepth 1 "$TARGET" -printf "$TARGET%P\n" | sort | uniq -d | xargs rm
    – DevOps
    Jul 4, 2017 at 16:07
1

A much quicker way to check for differences between directories:

diff -qr "$source" "$target"

Another solution is to ask find specifically for files only by using -type f.

You can also suppress the printing of the starting points by using -mindepth 1.

0

try this

SOURCE=folder1/ ;
TARGET=folder2/ ;
find  "$SOURCE" "$TARGET" -type f -printf "$TARGET%P\n" | sort | uniq -d | xargs rm

Do not forget to append / in source and target path.

You must log in to answer this question.

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