Interesting bash subtlety

Discussion in 'NZ Computing' started by Lawrence D'Oliveiro, Oct 25, 2008.

  1. I was trying to ensure that a directory path in a Bash script always ended
    in a slash, as follows:

    if [ "${dir:-1:1}" != "/" ]; then
    dir="${dir}/"
    fi

    but it wouldn't work. The substitution "${dir:-1:1}" was supposed to give me
    the last character of the string in the variable "dir", but it was instead
    returning the whole string. Checked the Bash manual
    <http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion>:

    ${parameter:eek:ffset: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.

    Yup, that's what I wanted. Then I realized: "-1" is probably not valid as a
    numeric literal, I have to insert an _expression_ if I want it to evaluate
    to a negative number. And so this

    if [ "${dir:$((-1)):1}" != "/" ]; then
    dir="${dir}/"
    fi

    worked!
     
    Lawrence D'Oliveiro, Oct 25, 2008
    #1
    1. Advertising

  2. In message <gdui8s$o0b$>, Lawrence D'Oliveiro wrote:

    > if [ "${dir:$((-1)):1}" != "/" ]; then
    > dir="${dir}/"
    > fi


    OK, what the heck, this is simpler:

    dir="${dir%/}/"
     
    Lawrence D'Oliveiro, Oct 25, 2008
    #2
    1. Advertising

  3. Lawrence D'Oliveiro

    Enkidu Guest

    Lawrence D'Oliveiro wrote:
    > In message <gdui8s$o0b$>, Lawrence D'Oliveiro wrote:
    >
    >> if [ "${dir:$((-1)):1}" != "/" ]; then
    >> dir="${dir}/"
    >> fi

    >
    > OK, what the heck, this is simpler:
    >
    > dir="${dir%/}/"


    I was faced with something similar recently. I needed to test if a
    string ended in, say, 'xyz'. While the construct with '%' above strips
    any trailing /, I don't think that there is a construct that does the
    opposite - ie returns the matched string. So in the end I did

    if [ X$dir != X${dir%xyz} ]

    There's probably a better way.

    Cheers,

    Cliff

    --

    Tax is not theft.
     
    Enkidu, Oct 26, 2008
    #3
  4. In message <4903ba3b$>, Enkidu wrote:

    > I needed to test if a string ended in, say, 'xyz'. While the construct
    > with '%' above strips any trailing /, I don't think that there is a
    > construct that does the opposite - ie returns the matched string.


    Try this:

    if [[ "$dir" =~ (.+)(xyz) ]]; then
    echo "${BASH_REMATCH[2]}"
    else
    echo no match.
    fi

    More details here
    <http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs>.
     
    Lawrence D'Oliveiro, Oct 26, 2008
    #4
  5. Lawrence D'Oliveiro

    John Little Guest

    On Oct 25, 8:35 pm, Lawrence D'Oliveiro <l...@geek-
    central.gen.new_zealand> wrote:
    > I was trying to ensure that a directory path in a Bash script always ended
    > in a slash...


    The usual reason I see people doing this is to make sure there's a
    slash before appending a file name. There's no need, extra redundant
    slashes are ignored; f. ex. //tmp//foo//bar is the same file as /tmp/
    foo/bar.

    Regards, John
     
    John Little, Oct 26, 2008
    #5
  6. Lawrence D'Oliveiro

    Enkidu Guest

    Lawrence D'Oliveiro wrote:
    > In message <4903ba3b$>, Enkidu wrote:
    >
    >> I needed to test if a string ended in, say, 'xyz'. While the construct
    >> with '%' above strips any trailing /, I don't think that there is a
    >> construct that does the opposite - ie returns the matched string.

    >
    > Try this:
    >
    > if [[ "$dir" =~ (.+)(xyz) ]]; then
    > echo "${BASH_REMATCH[2]}"
    > else
    > echo no match.
    > fi
    >
    > More details here
    > <http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs>.
    >

    Nice, but seems 'perlish' to me. I think my version is more bash.

    Cheers,

    Cliff

    --

    Tax is not theft.
     
    Enkidu, Oct 26, 2008
    #6
  7. Here's another fun one: I have some PostScript code for generating address
    labels, 30 to a page. I want to run the code through GhostScript to
    generate a raster at a specified pixel density (e.g. 720dpi for high
    quality) and then feed the result to my printer.

    I previously had this working with the PostScript code in one file,
    referenced by a shell script in another file. But it would be good to have
    everything self-contained in one file. Simplifying a bit, the command
    sequence originally looked like

    gs address_labels.ps | some other manipulations | lpr

    where "some other manipulations" involved additional commands spanning
    several lines. I could insert the PostScript code into the gs command using
    a here-document, like this:

    gs <<EOD
    ... contents of address_labels.ps ...
    EOD

    but where could I put the "some other manipulations" part? This would work

    gs <<EOD | some other manipulations ...

    but the line would be long and ugly. Turned out this works as well:

    gs <<EOD |
    ... contents of address_labels.ps ...
    EOD
    some other manipulations | lpr

    Just the presence of the "|" at the end of the first line is sufficient for
    Bash to expect the command to continue after the end of the here-document.
     
    Lawrence D'Oliveiro, Oct 27, 2008
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. damon
    Replies:
    7
    Views:
    10,612
    cartersanders
    Aug 29, 2007
  2. steelneck

    Bash script and sessioncookies

    steelneck, Feb 23, 2005, in forum: Firefox
    Replies:
    2
    Views:
    1,083
    steelneck
    Feb 25, 2005
  3. DerekC
    Replies:
    0
    Views:
    650
    DerekC
    Oct 9, 2004
  4. Brian Nobble

    I'll Bash my head in

    Brian Nobble, Sep 29, 2003, in forum: Computer Support
    Replies:
    11
    Views:
    795
    Reverend Parson Peter Parsnip
    Oct 2, 2003
  5. Boomer

    [Game] Bash The Haggis

    Boomer, Jul 13, 2004, in forum: Computer Support
    Replies:
    26
    Views:
    1,460
    geothermal
    Oct 16, 2004
Loading...

Share This Page