1

I am trying to make an if-statement that says:

If a file in this directory has .PDF extension do this, otherwise do this...

And I'm having a hard time figuring out how to do this in bash. I checked here : https://stackoverflow.com/questions/3856747/check-whether-a-certain-file-type-extension-exists-in-directory

first but the solutions listed either don't work or give errors I don't know how to fix.

Attached below is my script. I slightly modified the script I was working on in my previous question here: Change only the extension of a file

The script is below:

#!/bin/bash
#shebang for bourne shell execution
echo "Hello this is task 1 of the homework"
 #Initial prompt used for testing to see if script ran

#shopt allows configuration of the shell -s dotglob allows the script to run on dot-files shopt -s dotglob

#loop to iterate through each file in Task1 directory and rename them #loop runs if there is a file type of ".PDF" in the folder Task1, if there isn't displays that there i sn't a file of that type and terminates if [ [ -n $(echo *.PDF) ] ] # what should I put here???
then for file in Task1/*.PDF; do

            mv "$file" "${file%.PDF}.pdf"
            echo "$file has been updated"
    done

else echo "No files of that type..." fi ~

**Edit 1: **

As per Ipor Sircer's answer below I changed my script to the following:

#!/bin/bash
#shebang for bourne shell execution
echo "Hello this is task 1 of the homework"
 #Initial prompt used for testing to see if script ran

#shopt allows configuration of the shell -s dotglob allows the script to run on dot-files shopt -s dotglob

#loop to iterate through each file in Task1 directory and rename them #loop runs if there is a file type of ".PDF" in the folder Task1, if there isn't displays that there isn't a file of that type and terminates if [ ls -1 *.PDF|xargs -l1 bash -c 'mv $0 ${0%.PDF}.pdf' ] then for file in Task1/*.PDF; do

            mv "$file" "${file%.PDF}.pdf"
            echo "$file has been updated"
    done

else echo "No files of that type..." fi

I get the following errors:

Hello this is task 1 of the homework

./Shell1.sh: line 12: [: missing `]'

mv: cannot stat ']': No such file or directory

No files of that type...

Edit 2

As per Eric Renouf's comment fixing the spacing gives me the following script:

#!/bin/bash
#shebang for bourne shell execution
echo "Hello this is task 1 of the homework"
 #Initial prompt used for testing to see if script ran

#shopt allows configuration of the shell -s dotglob allows the script to run on dot-files shopt -s dotglob

#loop to iterate through each file in Task1 directory and rename them #loop runs if there is a file type of ".PDF" in the folder Task1, if there isn't displays that there isn't a file of that type and terminates if [[ -n $(echo *.PDF) ]] then for file in Task1/*.PDF; do

            mv "$file" "${file%.PDF}.pdf"
            echo "$file has been updated"
    done

else echo "No files of that type..." fi

However if I run it twice I see the following:

Hello this is task 1 of the homework

mv: cannot stat 'Task1/*.PDF': No such file or directory

Task1/*.PDF has been updated

Why don't I just see the else echo since there are no files of type .PDF in the folder anymore?

Callat
  • 243
  • 3
  • 9
  • Don't put spaces between the brackets, but do after. [ [ is different from [[ – Eric Renouf Jan 24 '17 at 16:44
  • Do yourself a favor and start searching for answers on this site instead of SO e.g. Check if a folder has a certain type of file present – don_crissti Jan 24 '17 at 16:47
  • @EricRenouf that actually fixed my problem but now that the files are updated I should be getting the else echo but instead I get new errors please see Edit 2 – Callat Jan 24 '17 at 16:56
  • @don_crissti I'll have to start doing that. I usually do a google query and those usually end with me in SO. – Callat Jan 24 '17 at 16:57
  • What is the purpose of this exercise (how is it different than your previous Q) ? What are you trying to accomplish ? Do you just want to print a message if no files match that glob pattern else rename the matches ? – don_crissti Jan 24 '17 at 17:00
  • @don_crissti I am trying to make a script that looks at the extensions of files in a folder and if they have .PDF change it to .pdf,if they are .PDF.PDF change to .PDF.pdf and lastly if they are say .tempname.PDF.PDF change to .tempname.PDF.pdf. It's supposed to echo with each change and if they are no files change say so and end.I've been working at it in pieces over the past few days but since I've never used bash I keep getting stuck . – Callat Jan 24 '17 at 17:04
  • 1
    And why can't you just write that in your question instead of the above stuff which makes almost no sense ? Also, you do realize that if .PDF is to be changed to .pdf that implies that .PDF.PDF will also be changed to .PDF.pdf (i.e. it doesn't matter what's before the extension) ? – don_crissti Jan 24 '17 at 17:06

3 Answers3

2
shopt -s nullglob

set -- Task1/*.PDF

if (( $# > 0 )); then
   printf 'There are %d PDF files in "Task1"\n' "$#"
else
   echo 'There are no PDF files in "Task1"'
fi

The set will set the positional parameters to the names of the individual PDF files available in the Task1 sub-directory. This is the same as if you had invoked the script with ./script Task1/*.PDF.

The number of positional arguments is held in $# and we test to see if this is greater than zero. If it is, we report the number of PDF files available. Otherwise we report that there are none. You may choose to do whatever you want in place of these two actions.

If the task is just to lowercase the .PDF suffix of any such file, then it is unnecessary to first check whether there are any:

shopt -s nullglob

for fpath in Task1/*.PDF; do
  mv "$fpath" "${fpath%.PDF}.pdf"
done

Setting the nullglob shell option ensures that we don't end up with a value of * in fname if there weren't any files matching the pattern.

Kusalananda
  • 333,661
0
ls -1 *.PDF|xargs -l1 bash -c 'mv $0 ${0%.PDF}.pdf'
Ipor Sircer
  • 14,546
  • 1
  • 27
  • 39
0

Could you just use:

[ -e *.PDF ]

instead of

[ [ -n $(echo *.PDF) ] ] 

e.g.

[ -e *.PDF ] && echo 'yes'
Kusalananda
  • 333,661
  • Not sure why but trying to apply this gives me a bad interpretter error. – Callat Jan 24 '17 at 17:13
  • After some testing for some reason I removed part of the shebang I put it back and it works but I still have the same problem with the else statement – Callat Jan 24 '17 at 17:26
  • @don_crissti Yes I tried it out. Unfortunately I only tested with one .PDF file existing. With 2 I get an error. I intend to post that as a question – Michael Durrant Jan 24 '17 at 18:26
  • This only works if there are 0 or 1 matching files. If there are multiple matches then the pattern expands to yield a syntactically incorrect command. – Gilles 'SO- stop being evil' Jan 25 '17 at 00:26