about summary refs log tree commit diff
path: root/doc/case.html
blob: 8ae817b279c6fbc4e734e7bdb5cf5dd8d0e524dd (plain) (blame)
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<html>
 <head>
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <meta http-equiv="Content-Language" content="en" />
 <title>execline: the case command</title>
 <meta name="Description" content="execline: the case command" />
 <meta name="Keywords" content="execline command case regex grep" />
 <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
</head>
<body>

<p>
<a href="index.html">execline</a><br />
<a href="//skarnet.org/software/">Software</a><br />
<a href="//skarnet.org/">skarnet.org</a>
</p>

<h1> The <tt>case</tt> program </h1>

<p>
<tt>case</tt> compares a value against a series of regular expressions,
and executes into a program depending on the first expression the value
matches.
</p>

<h2> Interface </h2>

<p>
 In an <a href="execlineb.html">execlineb</a> script:
</p>

<pre>
     case [ -S | -s ] [ -E | -e ] [ -i ] [ -n | -N ] <em>value</em>
     {
       [ regex { <em>prog...</em> } ]
       [ regex { <em>prog...</em> } ]
       ...
     }
     <em>progdefault...</em>
</pre>

<ul>
 <li> <tt>case</tt> reads an argument <em>value</em> and a sequence of
directives in a <a href="el_semicolon.html">block</a>. </li>
 <li> Each directive is a regular expression followed by a block. </li>
 <li> <tt>case</tt> matches <em>value</em> against the regular expressions
in the order they are given. </li>
 <li> As soon as <em>value</em> matches a <em>regex</em>, <tt>case</tt>
executes into the <em>prog...</em> command line that immediately follows
the matched regex. </li>
 <li> If <em>value</em> matches no <em>regex</em>, <tt>case</tt>
eventually execs into <em>progdefault...</em>, or exits 0 if <em>progdefault...</em>
is empty. </li>
</ul>

<h2> Options </h2>

<ul>
 <li> <tt>-s</tt>&nbsp;: Shell matching. The <em>regex</em> words will not be
interpreted as regular expressions, but as shell expressions to be interpreted
via <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html">fnmatch()</a>.
The other options also change meanings, see the <em>Shell matching</em> section below. </li>
 <li> <tt>-S</tt>&nbsp;: Regular expression matching. This is the default. This
section, and all of the sections below except the <em>Shell matching</em> one,
assumes that it is the case. </li>
 <li> <tt>-e</tt>&nbsp;: Interpret the <em>regex</em> words as
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03">basic
regular expressions</a>. </li>
 <li> <tt>-E</tt>&nbsp;: Interpret the <em>regex</em> words as
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04">extended
regular expressions</a>. This is the default. </li>
 <li> <tt>-i</tt>&nbsp;: Perform case-insensitive matches. </li>
 <li> <tt>-N</tt>&nbsp;: Make the matching expression and
subexpressions available to <em>prog</em>'s environment. See the "Subexpression
matching" section below. </li>
 <li> <tt>-n</tt>&nbsp;: Do not transmit the matching expression and
subexpressions to <em>prog...</em> via the environment. This is the default. </li>
</ul>

<h2> Subexpression matching </h2>

<p>
 If the <tt>-N</tt> option has been given, and <em>value</em> matches a <em>regex</em>,
then <tt>case</tt> will run <em>prog</em> with a modified environment:
</p>

<ul>
 <li> The <tt>0</tt> variable will contain the <em>regex</em> that <em>value</em> matched. </li>
 <li> The <tt>#</tt> variable will contain the number of subexpressions in <em>regex</em>. </li>
 <li> For every integer <em>i</em> between 1 and the number of subexpressions (included), the
variable <em>i</em> contains the part of <em>value</em> that matched the <em>i</em>th subexpression
in <em>regex</em>. </li>
</ul>

<p>
 To retrieve that information into your command line in an execline script, you can use the
<a href="elgetpositionals.html">elgetpositionals</a> program.
</p>

<h3> An example </h3>

<p>
 Consider the following script; say it's named <tt>match</tt>.
</p>

<pre>#!/bin/execlineb -S1
emptyenv
case -N -- $1
{
  "([fo]+)bar(baz)" { /usr/bin/env }
}
</pre>

<p>
 Running <tt>match foooobarbaz</tt> will print the following lines, corresponding
to the output of the <tt>/usr/bin/env</tt> command:
</p>

<pre>#=2
0=([fo]+)bar(baz)
1=foooo
2=baz
</pre>

<h2> Shell matching </h2>

<p>
 If the <tt>-s</tt> option has been given to <tt>case</tt>, then the <em>regex</em>
words are not interpreted as regular expressions, but as shell patterns, as is
performed by the shell's
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04_05">case</a>
conditional construct. This has the following consequences:
</p>

<ul>
 <li> Subexpression matching is always disabled. </li>
 <li> <em>prog...</em> is always executed with an unmodified environment. </li>
 <li> The options to the <tt>case</tt> command change meanings: instead of
controlling how the <em>regex</em> regular expressions are interpreted by the
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/regcomp.html">regcomp()</a>
primitive, they now control how <em>value</em> is matched against the <em>regex</em> patterns
(which are not regular expressions!) via the
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html">fnmatch()</a>
primitive. Namely:
 <ul>
  <li> <tt>-e</tt>&nbsp;: Treat a backslash as an ordinary character; do not allow
character escaping in patterns. (This sets the <tt>FNM_NOESCAPE</tt> flag.) </li>
  <li> <tt>-E</tt>&nbsp;: Allow backslash escaping in patterns. This is the default.
(This clears the <tt>FNM_NOESCAPE</tt> flag.) </li>
  <li> <tt>-i</tt>&nbsp;: Treat a period (<tt>.</tt>) as a special character for
matching (set <tt>FNM_PERIOD</tt>). By default, the period is not a special character
(<tt>FNM_PERIOD</tt> is cleared). </li>
  <li> <tt>-N</tt>&nbsp;: Treat patterns as pathnames: make slashes character special.
(This sets the <tt>FNM_PATHNAME</tt> flag.) </li>
  <li> <tt>-n</tt>&nbsp;: Do not treat patterns as pathnames (clear the
<tt>FNM_PATHNAME</tt> flag). This is the default. </li>
 </ul> </li>
</ul>

<h2> Notes </h2>

<ul>
 <li> <em>value</em> must match <em>regex</em> as a full word. If only a substring of <em>value</em>
matches <em>regex</em>, it is not considered a match. </li>
 <li> If <em>value</em> matches no <em>regex</em>, <em>progdefault...</em> is always executed with an
unmodified environment, whether subexpression matching has been requested or not. </li>
</ul>

</body>
</html>