1

Essentially I need to create a code that backs up files. One of the specifications is that if there is a .pdf file (lets call it test1.pdf for example) and a .doc file with the exact same name (test1.doc) then the code is meant to only copy the .doc file.

Here's what I've got so far, the code does 90% of what it's meant to do except this final requirement. I've utilized a for loop:

for file in $(find "${sourcePath}" -name "*.pdf"); do
fileName=$(echo "${file}" | cut -d '.' -f1)
if $(find $(sourcePath) -name "${fileName}.doc" &>/dev/nulll; then
    echo "Sorry, a .doc file with that extension already exists, skipping copy"
    continue
fi
done

I'm sure people will find out instantly why it doesn't work (I'm just that bad) but essentially what this loop is doing when I run the script via bash -x is:

  1. Checks for any files with .pdf
  2. Removes the name before the .
  3. Checks for any other files with the same filename before the . and if it's a .doc file it echos a warning message
  4. Problem is, the code still copies the files anyway

I suspect it's because I've not specified WHAT the code should do if it finds the two files.

Here's my full code for reference.

#!/bin/bash
sourcePath=$1
destPath=$2
Filedoc="*.doc"
Filepdf="*.pdf"
FilePDF="*.PDF"

if [[ $# -ne 2 ]]; then
    echo "Usage ; dar doc_path archive_path"
    exit 1
fi

if [ ! -d sourcePath ]
    then echo Directory does not exist
fi

if [ ! -d destPath ]
    then mkdir -p $destPath
fi

for file in $(find "${sourcePath}" -type f -exec basename {} \; | sort | uniq -d); do
    num=1 
    fileName=$(echo "${file}" | cut -d '.' -f1)
    fileExtension=$(echo "${file}" | cut -d '.' -f2)
    dirName=$(dirname "${duplicate}")
    for duplicate in $(find "${sourcePath}" -name "${file}" | tail -n +2 ); do
            mv "${duplicate}" "${duplicate}${fileName}_${num}.${fileExtension}"
            echo "Renamed duplicate file ${duplicate} ${duplicate}_${num}.${fileExtension}"
            (( num = num + 1 ))
    done
done

for file in $(find "${sourcePath}" -name "*.pdf"); do
    fileName=$(echo "${file}" | cut -d '.' -f1)
    if $(find $(sourcePath) -name "${fileName}.doc" &>/dev/nulll; then
            echo "Sorry, a .doc file with that extension already exists, skipping copy"
            continue
        fi
done

find "${sourcePath}" -name "$Filedoc" -exec cp -r {} "${destPath}" \;
find "${sourcePath}" -name "$FilePDF" -exec cp -r {} "${destPath}" \;
  • Your code copies all pdf and doc file in the last 3 lines of your script. The second loop is useless, it doesn't do anything. You have to rethink your script. – cristi Nov 9 '15 at 11:55
  • How would you recommend that? Say I remove the .pdf find line at the end, how would I tell the script to copy .pdf files? – James Dean Nov 9 '15 at 12:03
  • you probably don't want to use that for loop. – mikeserv Nov 9 '15 at 13:51
  • Don't vandalize your questions. Once posted, questions and answers here are licensed with a CC licence and no longer belong to you. Defacing them is not allowed. Also, please don't post answers in the question. Post your solution as a separate answer and, if it worked for you, accept it. This question looks fine to me and I see no reason to delete it. Come ping me (@terdon) in chat if you want to discuss it. – terdon Nov 11 '15 at 13:57
0
cd -P  -- "$destpath"   &&
cd -P  -- "$sourcepath" || exit; d= \
find . -type f -name \*.pdf -exec sh -c '
    for   f
    do    [ -e    "${f%.*}.doc" ]|| 
          ! case   ${f#"$d"}     in
            */*)   d=${f%/*}/
            mkdir -p "$0/$d"     ;:
            esac  || cp "$f" "$0/$f"
    done'  "$OLDPWD" {} +
pax -rws"|.*\.pdf$||" . "$OLDPWD"

...which first individually copies all .pdf files in "$sourcepath" to "$destpath" which are are not named identically to some other .doc file and then copies the entire tree at once while excluding only .pdf files.

  • if it was just for kicks then hey, ok. but if i can learn anything from you, let me know what i've got wrong, maybe, downvoter? – mikeserv Nov 9 '15 at 19:18
  • oh. my bad. forgot about the separate paths. thanks downvoter. – mikeserv Nov 9 '15 at 19:28
-1

Don't try to cheat your homework.

The way I would do it: search for all pdf files first (in a loop), extract the filename of each file and check if a corresponding doc file exists in the same path. If the doc exists, copy only the doc file, if not, copy the pdf.

After that recopy all doc files (this will ensure that you get all doc files that don't have a backup pdf file).

Edit:

This is a pseudo code example of what I mean:

sourcePath=$1
destinationPath=$2

for all pdf files in $sourcePath; do
    crt_file_without_extension
    if crt_file_without_extension.doc exists
        copy doc file to $destinationPath
    else
        copy pdf file to $destinationPath
    fi
done

copy all doc files to $destinationPath
  • Don't I already have that? My loop (or to my knowledge) searches for all .pdf files, checks the name before the period then looks in the same directory (and sub directories) for any .doc files with the same filename and if it finds it then it produces the relevant echo. I've tried to add in an else right after the 'continue' in that else (if it doesn't find any identical .doc files) cp "${file}" "${destPath}". Is this wrong? – James Dean Nov 9 '15 at 12:11
  • No. Like I said your last 3 lines copy all doc and pdf files. – cristi Nov 9 '15 at 12:13
  • Yes, i've removed them (I removed the .pdf file line but kept the .doc and .PDF ones) I've removed it and altered the for loop to search for all .pdf files, checks the name before the period then looks in the same directory (and sub directories) for any .doc files with the same filename and if it finds it then it produces the relevant echo. I've tried to add in an else right after the 'continue' in that else (if it doesn't find any identical .doc files) cp "${file}" "${destPath}". Is this wrong? – James Dean Nov 9 '15 at 12:15
  • It's still wrong. You need to do the copy inside the for loop. – cristi Nov 9 '15 at 12:38
  • How would I go about doing this? I've tried everything. I've tried saying for any files with a .pdf extension in the source path then remove the extension and only keep the file name, if the filename is not equal to (if [[ ! "${fileName}" = *.doc) to .doc then copy the file. It just doesn't work. I'm obviously doing something wrong due to my limited knowledge but it's the structure that's killing me. Thanks for the replies anyway – James Dean Nov 9 '15 at 12:58

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.