Use parameter expansions to remove the .pdf
part like so:
shopt -s nullglob
files=( *.pdf )
echo "${files[@]%.pdf}"
The shopt -s nullglob
is always a good idea when using globs: it will make the glob expand to nothing if there are no matches.
"${files[@]%.pdf}"
will expand to an array with all the trailing .pdf
removed. You can, if you wish put this in another array as so:
files_noext=( "${files[@]%.pdf}" )
All this is 100% safe regarding funny symbols in filenames (spaces, newlines, etc.), except for the echo
part for files named -n.pdf
, -e.pdf
and -E.pdf
... but the echo
was just here for demonstration purposes. Your files=( $(ls *.pdf) )
is really really bad! Do never parse the output of ls
.
To answer your comment: substring expansions don't work on each field of the array. Taken from the reference manual linked above:
${parameter:offset}
${parameter:offset:length}
If offset
evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter
. If length
evaluates to a number less than zero, and parameter
is not @
and not an indexed or associative array, it is interpreted as an offset from the end of the value of parameter
rather than a number of characters, and the expansion is the characters between the two offsets. If parameter
is @
, the result is length
positional parameters beginning at offset. If parameter
is an indexed array name subscripted by @
or *
, the result is the length
members of the array beginning with ${parameter[offset]}
. A negative offset is taken relative to one greater than the maximum index of the specified array. Substring expansion applied to an associative array produces undefined results.
So, e.g.,
$ array=( zero one two three four five six seven eight )
$ echo "${array[@]:3:2}"
three four
$