Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Computing > NZ Computing > Interesting bash subtlety

Reply
Thread Tools

Interesting bash subtlety

 
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      10-25-2008
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>:

${parameterffset: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!
 
Reply With Quote
 
 
 
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      10-25-2008
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%/}/"
 
Reply With Quote
 
 
 
 
Enkidu
Guest
Posts: n/a
 
      10-26-2008
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.
 
Reply With Quote
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      10-26-2008
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>.
 
Reply With Quote
 
John Little
Guest
Posts: n/a
 
      10-26-2008
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
 
Reply With Quote
 
Enkidu
Guest
Posts: n/a
 
      10-26-2008
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.
 
Reply With Quote
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      10-27-2008
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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Ruby conditionals subtlety? Farhad Farzaneh Ruby 17 02-21-2010 09:44 PM
bash: ./firefox-installer: /bin/sh: bad interpreter: Permission denied damon Firefox 7 08-29-2007 08:50 PM
(patch for Bash) GTK+2 + Bash William Park XML 3 07-14-2005 12:09 AM
Bash script and sessioncookies steelneck Firefox 2 02-25-2005 11:50 AM
Language Subtlety or Compiler bug? Ned Harding C++ 7 09-01-2004 09:41 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57