Issue
I am a non-programmer experimenting more than anything by writing a commandline based system to write a blog.
I have the following as part of a longer script:
# Find & list out files
filefind (){
files=( */*.md )
PS3="$MSG" ;
select file in "${files[@]}"; do
if [[ $REPLY == "0" ]]; then echo 'Bye!' >&2 ; exit
elif [[ -z $file ]]; then echo 'Invalid choice, try again' >&2
else break
fi
done
}
I would like to echo " No Files found. Enter 0 to exit"
if the folder is empty. I realise I would need another elif line to do this.
When I run this, as is, I always get a return of:
{ ~/Code/newblog } $ ./blog pp
1) /.md
Choose file to Publish, or 0 to exit:
Ideally I'd like only the message with exit option, but would also like to understand why the /.md is returned. Apologies if this is answered elsewhere, hard to know what to look for if you don't know what to look for..! Happy to be pointed in the right direction.
Solution
My two cents:
As mostly I try to not use shopt
in my scripts, I would like to present the way I use for this:
First, in every script I write, I use a die
function:
#!/bin/bash
progName=${0##*/}
die() {
echo "ERROR $progName: $*" >&2
exit 1
}
Then for searching for files, I use:
pattern='*/*.md'
files=($pattern)
[[ -e ${files[0]} ]] || die "No files matching '$pattern' found."
test -e $variable
check for existance of entry (file, dir, block, link, character, pipe, socket, or else...).
[[ -f ${files[0]} ]] || die "No files matching '$pattern' found."
Will check that first entry is a file.
Using shopt
anyway, but playing with extglob
:
The extglob
permit a lot of things! One of my favorite is negation pattern.
For sample, if you may backup your file by adding bak
at begin or end of filename, but keeping extention: bak_file-1234.md
or file-1234_bak.md
, you could use on of them:
shopt -s extglob
pattern='*/!(bak_*).md' # Avoid filename that begin by bak_
pattern='*/!(*_bak).md' # Avoid filename that end by _bak
pattern='*/!(*_bak|bak_*).md' # Avoid both.
Full script sample
#!/bin/bash
progName=${0##*/}
die() { echo "ERROR $progName: $*" >&2; exit 1 ;}
shopt -s extglob
pattern='*/!(*_bak).md'
files=($pattern)
[[ -e ${files[0]} ]] || die "No files matching '$pattern' found."
for i in "${!files[@]}"; do
file=${files[i]}
printf 'Processing file %d/%d: \47%s\47.\n' $i ${#files[@]} "$file"
: Doing something with "$file"...
done
Answered By - F. Hauri - Give Up GitHub Answer Checked By - Gilberto Lyons (WPSolving Admin)