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

user3360140
  • 281
  • 1
  • 4
  • 14

4 Answers4

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

Eric Renouf
  • 939
  • 8
  • 19
  • just wondering, if I have lots of files in my target will using find be faster? – user3360140 Jul 07 '17 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 – Eric Renouf Jul 07 '17 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

DevOps
  • 720
  • 5
  • 16
  • 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 04 '17 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.

l0b0
  • 1,140
  • 1
  • 8
  • 17
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.

Gerald Schneider
  • 23,274
  • 8
  • 57
  • 89
Sunil Bhoi
  • 189
  • 1
  • 2
  • 9