I'm trying to parse the variable A_DESTINATION (a directory) and only call out the words in between the /.../

case "$TR_TORRENT_INFO" in

test="$(egrep '\/([^/.]+)\/$' $A_DESTINATION)"
echo test

I've gotten a regex in my script but it's not returning the folder successfully (i.e. in this case, /Miscellaneous/) in my log. It's just displaying this:

+ A_DESTINATION=/mnt/sda1/Miscellaneous/
+ egrep \/([^/.]+)\/$ /mnt/sda1/Miscellaneous/
+ test=
+ echo test

What am I doing wrong? Thanks!

  • 3
    grep works against files, not arguments. You're passing the var as an argument, and so grep is treating the argument it as a file to search. Also, why not use basename?
    – phemmer
    Feb 18, 2018 at 3:16
  • I can't use basename because I need the directory (i.e. /Movies/) before the file, not the file. Thanks for the info... how can I use grep or an equivalent on an argument?
    – Galevux
    Feb 18, 2018 at 4:59
  • You can echo "$A_DESTINATION" | egrep ... or (if your shell supports here-strings) egrep ... <<< "$A_DESTINATION". OTOH if you omit the trailing / in your assignments you could likely use the shell's built in parameter manipulation e.g. "/${A_DESTINATION##*/}/" Feb 18, 2018 at 9:20

2 Answers 2


Instead of adding a final directory suffix to $A_DESTINATION and then extracting it again with grep or whatever, why not just use a separate variable (e.g. $final) in the case statement and add that to $A_DESTINATION afterwards? For example:

case "$TR_TORRENT_INFO" in
    *test1.com*) final='Books' ;;
    *test2.com*) final='Movies' ;;
    *test3.com*) final='Music' ;;
              *) final='Miscellaneous' ;;


echo "$final"

This works, is simpler and, IMO, is also easier to read.

BTW, the single-quotes around Books, Movies, etc aren't strictly necessary (because there are no spaces or shell metacharacters in the strings), but they don't hurt and IMO single-quoting fixed strings is a good-habit to get into. It's also a reminder to use single-quotes if you want to add another case with a space in the final directory name (e.g. maybe something like final='Other Junk' ;;)


Following steeldrive's suggestion of leaving off the trailing / in the assignments:

case "$TR_TORRENT_INFO" in
    *test1.com*) A_DESTINATION="$A_DESTINATION/Books"  ;;
    *test2.com*) A_DESTINATION="$A_DESTINATION/Movies" ;;
    *test3.com*) A_DESTINATION="$A_DESTINATION/Music"  ;;
    *) A_DESTINATION="$A_DESTINATION/Miscellaneous"

... or use a variable to hold the added path element as cas suggests, which will be easier to read.

This will allow you to use either the basename utility or the ${parameter##word} parameter substitution to get at the final part of the path in $A_DESTINATION.

The basename of a pathname does not need to be a file. It's simply the last part of a path:

printf 'basename is "%s"\n' "${A_DESTINATION##*/}"


printf 'basename is "%s"\n' "$( basename "$A_DESTINATION" )"

When you later add a filename to the path, then include the / path separator:


Your egrep command:

egrep '\/([^/.]+)\/$' $A_DESTINATION

This will instruct egrep to read $A_DESTINATION as a file and apply the given regular expression to it.

The following would have worked (assuming no trailing /), but you should use the above mentioned solution instead:

printf '%s\n' "$A_DESTINATION" | grep -o '[^/]*$'

Don't use test as the name of a variable as it is also the name of a standard command. There is no risk of "overloading" the command test, but it would potentially make the code confusing to read.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .