~nabijaczleweli/voreutils

ref: 72087d46a1d3f95f4e58bc8d4803aa05ab64b9f0 voreutils/man/expr.1 -rw-r--r-- 9.3 KiB
72087d46наб OpenBSD port 2 months ago
                                                                                
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
.\" SPDX-License-Identifier: 0BSD
.\"
.Dd
.Dt EXPR 1
.Os
.
.Sh NAME
.Nm expr
.Nd evaluate expression
.Sh SYNOPSIS
.Nm
.Cm \&( Ar expr Cm \&) Oo Cm op Ar expr Oc Ns 
.Nm
.Cm + Ar argument , Cm match Ar string regex , Cm length Ar string , Cm index Ar string characters , Cm substr Ar string position length Oo Cm op Ar expr Oc Ns 
.Nm
.Ar string Cm \&: Ar regex Oo Cm op Ar expr Oc Ns 
.Nm
.Ar integer Bro Cm * , / , % Brc Ar integer Oo Cm op Ar expr Oc Ns 
.Nm
.Ar integer Bro Cm + , \- Brc Ar integer Oo Cm op Ar expr Oc Ns 
.Nm
.Ar expr Bro Cm < , <= , = , != , >= , > Brc Ar expr Oo Cm op Ar expr Oc Ns 
.Nm
.Ar expr Cm & Ar expr Oo Cm op Ar expr Oc Ns 
.Nm
.Ar expr Cm \&| Ar expr Oo Cm op Ar expr Oc Ns 
.
.Sh DESCRIPTION
Writes the evaluation of the expression given as the arguments, followed by a newline, to the standard output stream.
Many of the operators
.Pq Cm ()*<>&|\&
are special in shells \(em make sure to escape or stringify them.
.Pp
An expression qualifies as a number if it's a signed 64-bit integer
.Pq Bq Em \-9223372036854775808 , 9223372036854775807 ,
decimal, with only the optional
.Sq \-
allowed.
.Pp
All indices are
.Sy 1 Ns -based
according to characters in the current locale.
Each invalid multi-byte sequence is a separate character, but regular expressions stop matching at invalid sequences.
.
.Ss Operators
In chunked descending precedence; all binary operators left-associative.
.Pp
.Bl -tag -compact -width "match string regex"
.It Cm \&( Ar expr Cm \&)
.Ar expr
.Pp
.
.It Cm + Ar argument
Special case: immediately consumes
.Ar argument
(the next token) as a value, regardless of any special meaning.
.
.It Cm match Ar string regex
.Ar string Cm \&: Ar regex
.
.It Cm length Ar string
Character count in
.Ar string .
.
.It Cm index Ar string characters
The first position in
.Ar string
of any character from
.Ar characters ,
or
.Sy 0
if none.
.
.It Cm substr Ar string position length
.Bq Ar position , position No + Ar length
subsection of
.Ar string .
Empty if
.Ar position
or
.Ar length
are \[<=]
.Sy 0
or not integers.
.Pp
.
.It Ar string Cm \&: Ar regex
The length, of the match of the basic regular expression
.Ar regex
matched to
.Ar string ,
anchored to the beginning
.Pq i.e. Ar regex No must match the start of Ar string No \(em this is similar to prepending a Qo Li ^ Qc to Ar regex ,
or
.Sy 0
if none.
.br
If
.Ar regex
has a capture group, evaluates to the first capture group
.Pq Li \e1 ,
or the null string if the match failed, instead.
.Pp
.
.\" Strictly, this should be expr-l not expr\-l (expr-dash-l not expr-minus-l), but it italicises better in -Tps, so
.It Ar "int  " Cm * Ar "int  "
Product of
.Ar int Ns s .
.
.It Ar int\-l Cm / Ar int\-r
.Ar int\-l
divided by
.Ar int\-r .
.
.It Ar int\-l Cm % Ar int\-r
Remainder from division of
.Ar int\-l
by
.Ar int\-r .
.Pp
.
.
.It Ar "int  " Cm + Ar "int  "
Sum of
.Ar int Ns s .
.
.It Ar int\-l Cm \- Ar int\-r
.Ar int\-r
subtracted from
.Ar int\-l .
.Pp
.
.It Ar expr Cm "< " Ar expr
.It Ar expr Cm "<=" Ar expr
.It Ar expr Cm " =" Ar expr
.It Ar expr Cm "!=" Ar expr
.It Ar expr Cm ">=" Ar expr
.It Ar expr Cm "> " Ar expr
If both expressions are integers, the result
.Pq Sy 0 No or Sy 1
of the corresponding comparison.
Otherwise, the result of the corresponding comparison between the strings according to the current locale's collating sequence (dictionary order).
.Pp
.
.\" TODO: select one
.It Ar expr\-l Cm & Ar expr\-r
If neither expression is the null string or
.Sy 0 :
.Ar expr\-l .
Otherwise
.Sy 0 .
.Pp
.
.It Ar expr\-l Cm \&| Ar expr\-r
If
.Ar expr\-l
is neither the null string nor
.Sy 0 :
.Ar expr\-l .
Otherwise, if
.Ar expr\-r
isn't the null string:
.Ar expr\-r .
Otherwise
.Sy 0 .
.Pp
.
.It Ar expr\-l Cm & Ar expr\-r
.Ar expr\-l
if neither expression is the null string or
.Sy 0 ;
otherwise
.Sy 0 .
.Pp
.
.It Ar expr\-l Cm \&| Ar expr\-r
.Ar expr\-l
if neither the null string nor
.Sy 0 ;
otherwise
.Ar expr\-r
if not the null string; otherwise
.Sy 0 .
.El
.
.Sh ENVIRONMENT
.Bl -tag -compact -width "EXPR_DUMP"
.It Ev EXPR_DUMP
If set, writes the final parse tree with parentheses around every expression, to the standard error stream.
This is a debugging feature and will be removed.
.\" TODO: remove
.El
.
.Sh EXIT STATUS
.Bl -tag -compact -width "I"
.It Sy 0
The expression evaluated to neither the null string nor
.Sy 0 .
.It Sy 1
The expression evaluated to the null string or
.Sy 0 .
.It Sy 2
Syntax error in expression, non-integer passed to an arithmetic operator, or division by zero.
.It Sy 3
Arithmetic overflow in
.Cm * , + , No or Cm \- .
.El
.
.Sh EXAMPLES
.Bd -literal -compact
.Li $ Nm Li 2 Cm + Li 2 Cm \e* Li 2
6
.Li $ Nm Cm \e( Li 2 Cm \e) + \e( Li 17 Cm \e* Li 2 Cm \e- Li 30 Cm \e) \e* \e( Li 5 Cm \e) + Li 2 Cm - \e( Li 8 Cm / Li 2 Cm \e) \e* Li 4
8

.Li $ Ev file Ns Li = Ns "'Makefile'\&;" Nm Li \&" Ns Ev $file Ns Li \&" Cm \&: Li "'.*/\e(.*\e)'" Cm \e| Li \&" Ns Ev $file Ns Li \&"
Makefile
.Li $ Ev file Ns Li = Ns "'/usr/src/voreutils/Makefile'\&;" Nm Li 
Makefile

.Li $ Ev file Ns Li = Ns "'Makefile'\&;" Nm Li \&" Ns Ev $file Ns Li \&" Cm \&: Li "'\e(/\e)[^/]*$'" Cm \e| Li \&" Ns Ev $file Ns Li \&" Cm \&: Li "'\e(.*\e)/'" Cm \e| Li '.'
\&.
.Li $ Ev file Ns Li = Ns "'/Makefile'\&;" Nm Li 
/
.Li $ Ev file Ns Li = Ns "'/usr/src/voreutils/Makefile'\&;" Nm Li 
/usr/src/voreutils

# However
.Li $ Ev file Ns Li = Ns "'length'\&;" Nm Li \&" Ns Ev $file Ns Li \&" Cm \&: Li "'.*/\e(.*\e)'" Cm \e| Li \&" Ns Ev $file Ns Li \&"
\&expr: .*/\e(.*\e): extraneous token
.Li $ Ev file Ns Li = Ns "'length'\&;" Nm Cm + Li \&" Ns Ev $file Ns Li \&" Cm \&: Li "'.*/\e(.*\e)'" Cm \e| + Li \&" Ns Ev $file Ns Li \&"
length
.Ed
.Pp
As part of a
.Xr sh 1
program:
.Bd -literal -compact
#!/bin/sh
.Nm Ar $# Cm \e<= Li 5 >/dev/null || {
.Li "   " Nm echo Li \&" Ns Ar $0 : Li Too many arguments" >&2
.Li "   " Nm exit Li 1
}
.Ed
.
.Sh SEE ALSO
Most arithmetic operations can be done using a
.Xr sh 1
arithmetic expression
.Pq Li $(( Ar expr Li )) ,
and basic string manipulation with parameter expansion operators
.Pq the Xr basename 1 Ns -like above can be written as Ev ${file##*/} , Cm length Li \&" Ns Ev $var Ns Li \&" No is Ev ${#var} , No &c.\& ;
these should be preferred for simple uses in new applications, as they're built into the shell and avoid unary operator SNAFUs.
.Pp
.Xr test 1 ,
.Xr strcoll 3 ,
.Xr mbrtowc 3 ,
.Xr locale 7 ,
.Xr regex 7
.
.Sh STANDARDS
Conforms to
.St -p1003.1-2008 ;
.Cm length , substr , index , No and Cm match
are explicitly unspecified, for compatibility with
.At v7 ,
and are scarcely supported in
.No non- Ns At
.Nm Ns s
.Pq Nx No supports Cm length , No citing GNU system compatibility; the list ends here .
Unary
.Cm +
is an extension, originating from the GNU system.
.Pp
Some
.Nm
implementations accept flags
.Pq like Fx Ns 's Fl e
\(em be wary of the first argument starting with a
.Fl ,
or start the argument list with a
.Fl - .
.
.Sh HISTORY
Appears in Edition 1.0 of The
.Tn PWB/UNIX
User's Manual, allowing
.Cm () , |&+-*/% , substr , length , No and Cm index ,
with the binary operators corresponding solely to their C equivalents on 16-bit
.Vt int Ns s .
.Pp
Edition 2.3 of The
.Tn CB-UNIX
Programmer's Manual sees 32-bit numbers,
.Cm \&| , & , Bro Cm = , > , >= , < , <= , != Brc , Cm +- , */% , No and Cm \&: ,
with
.Cm substr , length , No and Cm index
listed as
.Sx ARCHAIC FORMS .
.Cm \&|
is described simpler, as
.Ar expr\-l
if not nullary and
.Ar expr\-r
otherwise
.Pq with no Sy 0 Ns -folding ,
but the global behaviour is described as
.D1 Note that Sy 0 No is returned to indicate a zero value, rather than the null string .
The present-day behaviour matches and falls out of this.
The comparison operators for non-integers are byte-wise, owing to no system localisation.
.Cm \&:
rejects patterns with more than one capture group, but is otherwise as present-day.
Integer arguments to
.Cm substr
now default to
.Sy 0
instead of being required to be integers.
.Pp
.St -p1003.1-2008
notes that on some systems
.Cm \&:
is documented as literally injecting a
.Sy ^ ,
supposedly making another one in the pattern plain text, despite not doing so and selecting the match some other way \(em this is the case here.
Of interest is also that the
.Sx ARCHAIC FORMS
are such because they "have been made obsolete by the : operator" \(em the suggested replacements are:
.Bl -tag -compact -offset Ds -width "substr abcd 2 2 "
.It Cm substr Ar abcd 2 2
.Ar abcd Cm \&: Ar '..\e(..\e)'
\(em this is mostly reasonable, but more accurate as
.Ar '..\e(..\e?\e)' ,
and more generic as
.Ar '.\e{2\e}\e(.\e{1,2\e}\e)' .
.It Cm length Ar expr
.Ar expr Cm \&: Ar '.*'
.It Cm index Ar abcd d
.Ar abcd Cm \&: Ar d .
Not even close!
This is approximately seven centimeters down from explaining how
.Cm \&:
is anchored and what that entails.
Recreating
.Cm index
is very likely impossible with
.Cm \&: ,
even for a simple single-letter case.
.El
.Cm match
is also available, but wholly undocumented.  \" assuming it's the same as SysIII
.Pp
.At III
inherits the
.Tn CB-UNIX
manual page but strips it of the unary operators.
.Pp
.At V
removes
.Cm substr , length , No and Cm index .
.Pp
.At v7 ,
on the other hand, sees an
.Nm
compatible with
.Tn CB-UNIX Ns 's ,
but with an unrelated manual page, not mentioning the unary operators at all.
.Pp
.Bx 4.4
errors on
.Cm /%
dividing by zero instead of performing the division
.Pq which resolves to zero on the Tn PDP-11 No but a Dv SIGFPE No on the Tn VAX .