zsh-users
 help / color / mirror / code / Atom feed
* parameter expansion or regex question
@ 2005-02-17  3:03 Andy Spiegl
  2005-02-17  5:41 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Andy Spiegl @ 2005-02-17  3:03 UTC (permalink / raw)
  To: ZSH User List

In order to learn something new I decided to write a zsh script instead of
a perl script and now I'm stuck. :-(

The task is the following: I've got a filename consisting of any number of
words separated by dots, e.g.
 file.one.as.an.example
 another.file.txt
 just.one.more.to.show.off

This filename may (or may not) contain one of the strings
 q1 q2 q3 q4 q5
also separated by dots.  More examples:
 file.one.q4.as.an.example
 q3.another.file.txt
 just.one.more.to.show.q1.off

All I need now is the filename _without_ this "q<1-5>" string.
The problem is that this string is normally surrounded by dots
but not if it's at the beginning or end of the filename.
One hour ago I thought that I finally solved it (see code snippet below)
but then I found that it doesn't work if it e.g. contains the word "freq1."
or ".q3po.".  Oh, boy - it sounded so simple at first!

Well, here is my current attempt:
 (input: FILENAME, output: CLEANFILENAME)

post=${FILENAME#*q<1-5>.}
if [ x"$post" = x"$FILENAME" ]; then
  # no string found -> nothing to do
  CLEANFILENAME=$FILENAME
else
  pre=${FILENAME%q<1-5>.$post}
  # now pre is empty (q?.foobar.jpg) or terminates with a . (foo.q?.bar.jpg)
  if [ ! -n "$pre" ]; then
    CLEANFILENAME=$post
  elif [ ${pre%.} = $pre ]; then
    # no string found -> nothing to do
    CLEANFILENAME=$FILENAME
  else
    CLEANFILENAME=$pre$post
  fi
fi

In Perl I'd do it similar to this:
 FILENAME =~ /(^|.)q[1-5](.|$)/;
But I have no idea how/whether zsh can handle regexps.

Uffda, it's already way to late to think so I better go to bed now.
Hope to hear from you guys tomorrow.  Thanks,
 Andy.

-- 
                              o      _     _         _
  ------- __o       __o      /\_   _ \\o  (_)\__/o  (_)          -o)
  ----- _`\<,_    _`\<,_    _>(_) (_)/<_    \_| \   _|/' \/       /\\
  ---- (_)/ (_)  (_)/ (_)  (_)        (_)   (_)    (_)'  _\o_    _\_v
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Whenever I watch TV and see those poor starving kids all over the world,
 I can't help but cry. I mean I'd love to be skinny like that, but not with
 all those flies and death and stuff.     (Mariah Carey)


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: parameter expansion or regex question
  2005-02-17  3:03 parameter expansion or regex question Andy Spiegl
@ 2005-02-17  5:41 ` Bart Schaefer
  2005-02-18  0:15   ` Andy Spiegl
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2005-02-17  5:41 UTC (permalink / raw)
  To: Andy Spiegl, ZSH User List

On Feb 17,  4:03am, Andy Spiegl wrote:
}
} In Perl I'd do it similar to this:
}  FILENAME =~ /(^|.)q[1-5](.|$)/;
} But I have no idea how/whether zsh can handle regexps.

The closest approximation to (the corrected form of) that perl is:

setopt extendedglob
CLEANFILENAME="${FILENAME/((#s)|.)q<1-5>(.|(#e))/}"

Another regex-like way would be:
 
setopt extendedglob
CLEANFILENAME="${FILENAME/(#b)(#s)(|*).##q<1-5>.#(*|)(#e)/$match[1]$match[2]}"

But you could also use (no extendedglob needed):

CLEANFILENAME="${(j:.:)${(@)${(@s:.:)FILENAME}:#q<1-5>}}"

The latter two solutions need adjustment if the file name may contain
multiple consecutive dots.

The last splits the file into an array at dots, discards all elements
that look like q<1-5>, then joins the remainder back together again.

The way you were trying to do it:

prefix="${${${(M)FILENAME#*q<1-5>.}:-${FILENAME%.q<1-5>*}}%q<1-5>.}"
suffix="${${${(M)FILENAME%.q<1-5>*}:-${FILENAME#*q<1-5>.}}#.q<1-5>}"
CLEANFILENAME="${prefix}${suffix#.}"

Spelled out:

prefix="${(M)FILENAME#*q<1-5>.}"
if [[ -n "$prefix" ]]; then prefix="${FILENAME%.q<1-5>*}"; fi
prefix="${prefix%q<1-5>.}"

suffix="${(M)FILENAME%.q<1-5>*}"
if [[ -n "$suffix" ]]; then suffix="${FILENAME#*q<1-5>.}"; fi
suffix="${suffix#.q<1-5>}"
suffix="${suffix#.}"

CLEANFILENAME="${prefix}${suffix}"


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: parameter expansion or regex question
  2005-02-17  5:41 ` Bart Schaefer
@ 2005-02-18  0:15   ` Andy Spiegl
  0 siblings, 0 replies; 3+ messages in thread
From: Andy Spiegl @ 2005-02-18  0:15 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: ZSH User List

Hi Bart,

thanks so much for your reply.

> setopt extendedglob
> CLEANFILENAME="${FILENAME/((#s)|.)q<1-5>(.|(#e))/}"

> setopt extendedglob
> CLEANFILENAME="${FILENAME/(#b)(#s)(|*).##q<1-5>.#(*|)(#e)/$match[1]$match[2]}"

Great!  Hm, but both forget a dot if the q? is in the middle,
e.g. foo.bar.q1.baz leads to foo.barbaz

But no problem, cause I really like this one:
> CLEANFILENAME="${(j:.:)${(@)${(@s:.:)FILENAME}:#q<1-5>}}"
> 
> The last splits the file into an array at dots, discards all elements
> that look like q<1-5>, then joins the remainder back together again.

I actually like the sideeffect you mentioned concerning multiple
consecutive dots because it cleans up a "bad" filename.
Just out of curiosity, what adjustments would have to be made so that empty
array elements aren't ignored and thus multiple dots are kept? 

> The way you were trying to do it:
> 
> prefix="${${${(M)FILENAME#*q<1-5>.}:-${FILENAME%.q<1-5>*}}%q<1-5>.}"
> suffix="${${${(M)FILENAME%.q<1-5>*}:-${FILENAME#*q<1-5>.}}#.q<1-5>}"
> CLEANFILENAME="${prefix}${suffix#.}"
> 
> Spelled out:
> 
> prefix="${(M)FILENAME#*q<1-5>.}"
> if [[ -n "$prefix" ]]; then prefix="${FILENAME%.q<1-5>*}"; fi
> prefix="${prefix%q<1-5>.}"
> 
> suffix="${(M)FILENAME%.q<1-5>*}"
> if [[ -n "$suffix" ]]; then suffix="${FILENAME#*q<1-5>.}"; fi
> suffix="${suffix#.q<1-5>}"
> suffix="${suffix#.}"
> 
> CLEANFILENAME="${prefix}${suffix}"
Thanks for even correcting my solution - really interesting!
Ah, and now I even understand why your spelled-out version doesn't work!
You forgot the ! before the if-condition. :-)

Thanks again!
 Andy.

-- 
                              o      _     _         _
  ------- __o       __o      /\_   _ \\o  (_)\__/o  (_)          -o)
  ----- _`\<,_    _`\<,_    _>(_) (_)/<_    \_| \   _|/' \/       /\\
  ---- (_)/ (_)  (_)/ (_)  (_)        (_)   (_)    (_)'  _\o_    _\_v
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 The more things change, the more they remain the same.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-02-18  0:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-17  3:03 parameter expansion or regex question Andy Spiegl
2005-02-17  5:41 ` Bart Schaefer
2005-02-18  0:15   ` Andy Spiegl

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).