3

Basically, I have a folder /test/ that has a number of files of type .doc and .pdf. Some of the files have a .pdf and a .doc version, such as test.doc and test.pdf while others only have one version.

What I'm trying to do is find occurrences where there is a .doc and delete the corresponding .pdf using a script.

I've been tinkering with this line of code:

find /test/ -name "*.doc" - exec basename {} .doc \; -exec rm {}.pdf \;

However this returns the error that it cannot find files named example.doc.pdf instead of deleting the appropriately named .pdf from the find command. The reason I'm trying to do it this way is because there are .pdf files which don't have a matching .doc file which I do not wish to delete.

4

You can use this find command:

find /test/ -name "*.doc" -exec sh -c 'a="$1"; rm "${a%.doc}.pdf"' find-sh {} \;

It will search for .doc files in the directory /test/. For each found file a shell sh is called with the file as argument. ${a%.doc}.pdf replaces the file extension .doc with .pdf and rm removes it, if the file exists.

  • What does the find-sh part do? I'm tracking with everything but that part and how $1 in the sh call ends up holding the filename. – Wildcard Oct 13 '15 at 15:34
  • @Wildcard $1 is the first argument given to the script by {} at the end which holds the filename. This is stored in a variable $a to do variable substitution. find-sh is just the name I gave the script. It can be anything. – chaos Oct 13 '15 at 16:14
  • I see...am I correct in my understanding that you could omit find-sh and change the $1 to $0 and it would still work? – Wildcard Oct 13 '15 at 18:27
  • @Wildcard No, $0 is the filename of the current script, not an argument. – chaos Oct 13 '15 at 18:41
  • 1
    @Wildcard As I have written $0 is for the inline script name which is used for instance when displaying error messages. In the above example it contains find-sh. It becomes relevant when you call find with -exec sh -c '...' find-sh {} + (notice the +), because then "$@" contains the list of the arguments $1, $2, ..., without $0. So, in the above example it might work with $0, but keep that in mind. – chaos Oct 14 '15 at 5:39
1

Save the following script as rm_dub.sh

#!/bin/sh

rm_dub() {
    dir=$(dirname -- "$1")
    base=$(basename -- "$1" "$2")

    rm -- "$dir/$base$3"
}

rm_dub "$@"

and uses it with

find /test/ -name "*.doc" -exec sh rm_dub.sh {} .doc .pdf \;
  • I like the script but where does the actual deleting occur? – Wildcard Oct 13 '15 at 15:31
  • @Wildcard added the rm – Raphael Ahrens Oct 13 '15 at 15:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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