You are not logged in.

#1 2009-09-17 10:23:53

gladstone
Member
Registered: 2009-01-03
Posts: 74

[Bash] Variable exapansion and variables within variables

To make the following script more reusable, I wanted to refactor the "pattern" in a separate variable for the renameit2 function to use. However, it
currently doesn't work; "tr" throws an error:

tr: extra operand `\'-\''"

Can anyone explain how I can achieve what I'm trying to do?

Here is the complete script:

old="Hello THIS & test"
 
renameit() {
  new=$(echo $old | \
    tr ' ' '-' | tr -d '[{}(),\!]' | tr -d "\'" | tr '[A-Z]' '[a-z]' | \
    sed -e 's/---/-/g' -e 's/&/-and-/g' -e 's/--/-/g' -e 's/_/-/g')
  echo $new
}
 
PATTERN="
    tr ' ' '-' | tr -d '[{}(),\!]' | tr -d "\'" | tr '[A-Z]' '[a-z]' | \
    sed -e 's/---/-/g' -e 's/&/-and-/g' -e 's/--/-/g' -e 's/_/-/g'
"
 
renameit2() {
  new=$(echo $old | $PATTERN)
  echo $new
}
 
case $1 in
    old)
        renameit
    ;;
    new)
        renameit2
    ;;
esac

Offline

#2 2009-09-17 11:51:25

gnud
Member
Registered: 2005-11-27
Posts: 182

Re: [Bash] Variable exapansion and variables within variables

Hi,
I reworked your solution to use an array of sed expressions.
It becomes

patterns=(  "s/[A-Z]*/\L\\\&/g" #replace uppercase with lowercase (\L\&)
            "s/ /-/g" #replace spaces
            "s/[{}\(\),\\!]//g" #delete some special chars
            "s/\'//g" #delete the single quote
            "s/[\\d038]/-and-/g" #replace the amperstad (ascii no 38 decimal) 
            "s/_/-/g" #replace underscores with dashes
            "s/-\{2,\}/-/g" ) #translate all series of dashes to just one dash


renameit2() {
    new="$old"
    for p in "${patterns[@]}"
    do
        new=$(echo $new|sed -e "$p")
        if [ -z "$new" ] ; then
            echo "Failure at expression ${p}"
        fi
    done
    echo $new
}

You could possibly do some xargs magic to cut the loop, but I couldnt be bothered.
This makes it easy to redifine, add, remove, or reorder individual rules. I reordered some of your rules and joined some other together, and I think I eliminated some possible bugs.

Last edited by gnud (2009-09-17 11:56:07)

Offline

#3 2009-09-17 13:16:19

Cerebral
Forum Fellow
From: Waterloo, ON, CA
Registered: 2005-04-08
Posts: 3,108
Website

Re: [Bash] Variable exapansion and variables within variables

Yeah, I don't think you're going to get far the way you originally went - I think there's some bash-ism where it's passing all the single-quotes literally to tr and that's screwing it up.  I'd go with gnud's suggestion, but here it is a bit simpler:

#!/bin/bash

_patterns="
           s/[A-Z]*/\L\\\&/g   #replace uppercase with lowercase (\L\&)
           s/ /-/g             #replace spaces
           s/[{}\(\),\\!]//g   #delete some special chars
           s/\'//g             #delete the single quote
           s/[\\d038]/-and-/g  #replace the amperstad (ascii no 38 decimal)
           s/_/-/g             #replace underscores with dashes
           s/-\{2,\}/-/g       #translate all series of dashes to just one dash
"

renameit2() {
    _new=$(echo $old | sed -e "$_patterns")
    if [ -z "$_new" ] ; then
        echo "Sed failure."
    fi
    echo $_new
}

Offline

#4 2009-09-17 13:32:20

gladstone
Member
Registered: 2009-01-03
Posts: 74

Re: [Bash] Variable exapansion and variables within variables

gnud: Many thanks indeed! That seems to work brilliantly and it's quite an elegant method by my understanding of it.

I just had to change:

"s/\'//g" #delete the single quote

to

"s/'//g"

Cerebral: Thanks, that also works great. It's similar to how I would do things, indeed, it looks as though tr was the culprit.

Last edited by gladstone (2009-09-17 14:36:46)

Offline

Board footer

Powered by FluxBB