0

I have a bash script that looks through a directory and creates a .ppt from a .pdf, but i want to be able to check to see if there is a .pdf already for the .ppt because if there is I don't want to create one and if the .pdf is timestamped older then the .ppt I want to update it. I know for timestamp I can use (date -r bar +%s) but I cant seem how to figure out how to compare the files with the same name if they are in the same folder.

This is what I have:

#!/bin/env bash

#checks to see if argument is clean if so it deletes the .pdf and archive files
if [ "$1"  =  "clean" ]; then
rm -f *pdf

else
#reads the files that are PPT in the directory and copies them and changes the extension to .pdf

     ls *.ppt|while read FILE
        do

                NEWFILE=$(echo $FILE|cut -d"." -f1)
                echo $FILE": " $FILE " "$NEWFILE: " " $NEWFILE.pdf
                cp $FILE $NEWFILE.pdf 
 done 
 fi 

EDITS:

#!/bin/env bash

#checks to see if argument is clean if so it deletes the .pdf and archive files
    if [ "$1"  =  "clean" ]; then
    rm -f *pdf lectures.tar.gz

    else
#reads the files that are in the directory and copies them and changes the extension to .pdf

    for f in *.ppt
    do
            [ "$f" -nt "${f%ppt}pdf" ] &&
                    nf="${f%.*}"
                    echo $f": " $f " "$nf: " " $nf.pdf
                    cp $f $nf.pdf
    done
MDRIV3
  • 39
  • 1
  • 6

1 Answers1

1

To loop through all ppt files in the current directory and test to see if they are newer than the corresponding pdf and then do_something if they are:

for f in *.ppt
do
    [ "$f" -nt "${f%ppt}pdf" ] && do_something
done

-nt is the bash test for one file being newer than another.

Notes:

  1. Do not parse ls. The output from ls often contains a "displayable" form of the filename, not the actual filename.

  2. The construct for f in *.ppt will work reliably all file names, even ones with tabs, or newlines in their names.

  3. Avoid using all caps for shell variables. The system uses all caps for its variables and you do not want to accidentally overwrite one. Thus, use lower case or mixed case.

  4. The shell has built-in capabilities for suffix removal. So, for example, newfile=$(echo $file |cut -d"." -f1) can be replaced with the much more efficient and more reliable form newfile="${file%%.*}". This is particularly important in the odd case that the file's name ends with a newline: command substitution removes all trailing newlines but the bash variable expansions don't.

    Further, note that cut -d"." -f1 removes everything after the first period. If a file name has more than one period, this is likely not what you want. The form, ${file%.*}, with just one %, removes everything after the last period in the name. This is more likely what you want when you are trying to remove standard extensions like ppt.

Putting it all together

#!/bin/env bash

#checks to see if argument is clean if so it deletes the .pdf and archive files
if [ "$1"  =  "clean" ]; then
    rm -f ./*pdf lectures.tar.gz
else
    #reads the files that are in the directory and copies them and changes the extension to .pdf
    for f in ./*.ppt
    do
        if [ "$f" -nt "${f%ppt}pdf" ]; then
            nf="${f%.*}"
            echo "$f: $f $nf: $nf.pdf"
            cp "$f" "$nf.pdf"
        fi
    done
fi
John1024
  • 109,961
  • 14
  • 137
  • 171
  • 1
    Great collection of tips. I wish more people provided answers like this, rather than just one-liners of code without any explanation. – ghoti Aug 10 '16 at 04:21
  • @ghoti Thanks for that! – John1024 Aug 10 '16 at 04:22
  • Thank you for the great tips! I appreciate your time. It works now I am just trying to figure out a loop if the .pdf version does not exist, the comparison for that. – MDRIV3 Aug 10 '16 at 04:40
  • @MDRIV3 The test, as shown in the answer, will `do_something` if either (a) the ppt is newer than the pdf, or (b) the pdf doesn't exist. Did you want something different? – John1024 Aug 10 '16 at 04:44
  • @John1024 Maybe I did it wrong, I added my code edits. Is that correct? – MDRIV3 Aug 10 '16 at 04:53
  • @MDRIV3 OK. That `&& do_something` only works if the `do_something` is one command or a single group of commands. If we want to do several commands, then it is simpler to use `if-then`. See updated answer. – John1024 Aug 10 '16 at 05:13