Visit Our UNIX and Linux User Community


pattern matching question


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting pattern matching question
# 1  
Old 06-09-2011
pattern matching question

Hi guys
I have the following case statement in my script:
Code:
case $pn.$db in
   *?.fcp?(db))  set f ${pn} cp   ;;
   *?.oxa?(oxa) )  set oxa $pn  ;;
esac

Can somebody help me to understand how to interpret *?.fcp?(db)) or *?.oxa?(oxa) ?

I cannot figure out how in this case pattern maching works.
Thanks a lot for any advice .
# 2  
Old 06-09-2011
You seem to be using the Korn shell (or a shell that supports the ksh extended globbing - bash (with shopt -s extglob) or zsh (setopt kshglob).

This is the meaning of these patterns:

Code:
*?.fcp?(db)

* - matches any string, including the null string
? - matches any character
. - matches a literal dot
fcp - matches the literal string fcp
?(db) - matches 0 or 1 occurrences of the subpattern, the string db in this case.

Consider the following:

Code:
$ cat s
case $pn.$db in
   *?.fcp?(db)  ) printf '%s in the first case\n' "$pn.$db matched" ;;
   *?.oxa?(oxa) ) printf '%s in the second case\n' "$pn.$db matched" ;;
esac

Code:
$ pn=any_ db=fcp
$ . s
any_.fcp matched in the first case
$ pn=any_ db=fcpdb
$ . s
any_.fcpdb matched in the first case
$ pn=any_ db=fcpdbdb
$ . s
$
$ pn=any_ db=oxa
$ . s
any_.oxa matched in the second case

I hope this helps.
# 3  
Old 06-09-2011
I think I have it

First, lets take this as an example of why comments are necessary!

Ok in the case statement, the patterns to match follow the shell's file name generation patterns (*=any string, ?=any character, ?(patternlist)). So:
Code:
*?.fcp?(db))

(the *? means the first part must have at least 1 character)
means: if the pattern we are analyzing in the case ($pn.$db)
starts with at least 1 character and
ends in "fcp" or "fcpdb" then the pattern is matched.

If I am correct, this could be written in an easier to
follow way. Here's an example script using ksh that accepts 2 args which are then analyzed
by the case statement:
Code:
#!/bin/ksh

pn=$1
db=$2

# original code
case $pn.$db in
   *?.fcp?(db))  print 1
                 set f ${pn} cp   ;;
   *?.oxa?(oxa) )  print 2
                   set oxa $pn  ;;
esac

# Hopefully clearer code that shows the author's intentions.
case $pn.$db in
     *?.fcp) ;&  #  Fall through
   *?.fcpdb) print "first case"
            set f ${pn} cp
            ;;
     *?.oxa) ;&  #  Fall through
  *?.oxaoxa) print "Second case"
            set oxa $pn
            ;;
         *) # Always allow for the unexpected!
            print "Unknown value [$pn.$db]"
            exit 1
            ;;
esac

exit 0

Note the
Code:
     *.oxa) ;&  #  Fall through
  *.oxaoxa) print "Second case"

could be written as
Code:
*.oxa|*.oxaoxa)

Using a logical OR, but I am in the habit of splitting them up on their own lines in case in the future the developer maintaining this needs to take a different action on each case. The framework is already set up then.

Also, always allow for the default case which will catch unexpected values passed in!

Last edited by gary_w; 06-09-2011 at 06:05 PM..
# 4  
Old 06-09-2011
Quote:
Originally Posted by gary_w
[...]
I think the first ? is unnecessary
Depends on what needs to be matched. The * matches the null string too,
so the two patterns * and *? are different (the latter requires at least one character):

Code:
$ cat s
case $pn.$db in
   *?.fcp?(db)  ) printf '%s in the first case\n' "$pn.$db matched" ;;
   *.fcp?(db)  ) printf '%s in the second case\n' "$pn.$db matched" ;;
esac

Code:
$ pn= db=fcp
$ . s
.fcp matched in the second case
$ pn=a db=fcp
$ . s
a.fcp matched in the first case


Last edited by radoulov; 06-09-2011 at 06:08 PM..
This User Gave Thanks to radoulov For This Post:
# 5  
Old 06-09-2011
Good Catch!

Yes, it appears the case pattern means its pattern must start with at least 1 character. My example should have the ? too as in the original.
I will update my example. Thanks!

Last edited by gary_w; 06-09-2011 at 06:03 PM..
# 6  
Old 06-09-2011
Thanks a lot guys. It really helped me a lot.

Previous Thread | Next Thread
Test Your Knowledge in Computers #278
Difficulty: Easy
A monolithic kernel is an operating system architecture where the entire operating system is working in kernel space.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Bash pattern matching question

I need to check the condition of a variable before the script continues and it needs to match a specific pattern such as EPS-03-0 or PDF-02-1. The first part is a 3 or 4 letter string followed by a hyphen, then a 01,02 or 03 followed by a hyphen then a 0 or a 1. I know I could check for every... (4 Replies)
Discussion started by: stormcel
4 Replies

2. UNIX for Dummies Questions & Answers

Perl Pattern Matching Question

Hi all, I have a pattern matching problem in which i'm not sure how to attack. Here is my problem: I have a list of strings that appear in the following format: String: LE_(1234 ABC)^2^ABC^DEFG What i need to do is replace all the characters after the first ^ with blank. So the output... (2 Replies)
Discussion started by: WongSifu
2 Replies

3. Shell Programming and Scripting

sed pattern matching question

I inherited a script that contains the following sed command: sed -n -e '/^.*ABCD|/p' $fileName | sed -e 's/^.*ABCD|//' | sed -e 's/|ABCD$//' > ${fileName}.tmp What I'm wondering is whether ABCD has a special pattern matching value in sed, such as a character class similar or identical to . ... (9 Replies)
Discussion started by: topmhat
9 Replies

4. Shell Programming and Scripting

pattern matching question

Hi Guys I am trying to check if the pattern "# sign followed by one or several tabs till the end of the line" exists in my file. I am using the following query: $ cat myfile | nawk '{if(/^#\t*$/) print "T"}' Unfortunately it does not return the desired output since I know for sure that the line... (4 Replies)
Discussion started by: aoussenko
4 Replies

5. Shell Programming and Scripting

Pattern matching question

Hi Guys, I am trying to setup a check for the string using an "if" statement. The valid entry is only the one which contain Numbers and Capital Alpha-Numeric characters, for example: BA6F, BA6E, BB21 etc... I am using the following "if" constract to check the input, but it fails allowing Small... (3 Replies)
Discussion started by: aoussenko
3 Replies

6. Shell Programming and Scripting

pattern matching question

Hi guys, I have a file in the following format: 4222 323K 323L D222 494 8134 A023 A024 49 812A 9871 9872 492 A961 A962 A963 491 0B77 0B78 0B79 495 0B7A 0B7B 0B7C 4949 WER9 444L 999O I need to grep the line... (5 Replies)
Discussion started by: aoussenko
5 Replies

7. Shell Programming and Scripting

Pattern matching question

Hi, I am writing a simple log parsing system and have a question on pattern matching. It is simply grep -v -f patterns.re /var/log/all.log Now, I have the following in my logs Apr 16 07:33:17 ad-font-dc1 EvntSLog: AD-FONT-DC1/NTDS ISAM (700) - "NTDS (384) NTDSA: Online defragmentation... (5 Replies)
Discussion started by: wpfontenot
5 Replies

8. Shell Programming and Scripting

SED Question: Search and Replace start of line to matching pattern

Hi guys, got a problem here with sed on the command line. If i have a string as below: online xx:wer:xcv: sdf:/asdf/http:https-asdfd How can i match the pattern "http:" and replace the start of the string to the pattern with null? I tried the following but it doesn't work: ... (3 Replies)
Discussion started by: DrivesMeCrazy
3 Replies

9. Shell Programming and Scripting

Pattern matching question

Hi guys, I have the following expression : typeset EXBYTEC_CHK=`egrep ^"+${PNUM}" /bb/data/firmexbytes.dta` can anybody please explain to me what ^"+${PNUM}" stands for in egrep statement? Thanks -A (3 Replies)
Discussion started by: aoussenko
3 Replies

10. Shell Programming and Scripting

pattern matching + perl question

i can only find the first occurance of a pattern how do i set it to loop untill all occurances have changed. #! /usr/bin/perl use POSIX; open (DFH_FILE, "./dfh") or die "Can not read file ($!)"; foreach (<DFH_FILE>) { if ($_ !~ /^#|^$/) { chomp; ... (1 Reply)
Discussion started by: Optimus_P
1 Replies

Featured Tech Videos