1

I have the following function split in my .bash_profile file.

function split {
   name="${$1%.*}"
   ext="${$1##*.}"
   echo filename=$name extension=$ext
}

Now I should expect that the command split foo.bar will give me

filename=foo  extension=bar

But I get get -bash: ${$1%.*}: bad substitution error message. The same however works for usual shell variable in a shell script, say $x instead of $1 in .bash_profile (I think the same goes in .bashrc as well).

What's wrong and any remedy?

hbaromega
  • 171
  • 2
  • 8
  • And you *do* need quotes where you are passing variables to the `echo` command. – Wildcard Sep 28 '16 at 20:09
  • @Wildcard Maybe grammatically I need to quote after echo. But without quote works in many shells. Also I may skip quotes for variables `name` and `ext` as already pointed out by @SatoKatsura. – hbaromega Sep 28 '16 at 21:40
  • No, it doesn't "work," it does something else entirely. Your variables will be word split and subjected to glob expansion. Only by accident will you get the results you expect. See [Why does my shell script choke on whitespace or other special characters?](http://unix.stackexchange.com/q/131766/135943) and [Security implications of forgetting to quote a variable in bash/POSIX shells](http://unix.stackexchange.com/q/171346/135943). – Wildcard Sep 28 '16 at 22:32

2 Answers2

5

Drop the $ preceding the variable name (1) inside the parameter expansion:

name="${1%.*}"
ext="${1##*.}"

you are already referring to the variable with the $ preceding the starting brace {, no need for another one in front of the variable name.

heemayl
  • 54,820
  • 8
  • 124
  • 141
1

If you have the dirname, basename and awk commands, you might want to consider this function definition

function split {

DIR=$(/bin/dirname "$1")
BASE=$(/bin/basename "$1")
EXT=$(echo "$BASE" | /usr/bin/awk -F. 'NF>1 {print $NF}')
NAME=${BASE%.$EXT}
echo directory=$DIR filename=$NAME extension=$EXT

}

split good.bye/data.txt
split good.bye/data
split data.txt
split good.bye/data.001.txt
split "good bye/data 001.txt"
LouisB
  • 291
  • 1
  • 2
  • 6