OILS / spec / var-op-strip.test.sh View on Github | oils.pub

398 lines, 210 significant
1## compare_shells: dash bash mksh zsh ash
2
3#### Remove const suffix
4v=abcd
5echo ${v%d} ${v%%cd}
6## stdout: abc ab
7
8#### Remove const prefix
9v=abcd
10echo ${v#a} ${v##ab}
11## stdout: bcd cd
12
13#### Remove const suffix is vectorized on user array
14a=(1a 2a 3a)
15argv.py ${a[@]%a}
16## stdout: ['1', '2', '3']
17## status: 0
18## N-I dash/mksh/ash stdout-json: ""
19## N-I dash/ash status: 2
20## N-I mksh status: 1
21
22#### Remove const suffix is vectorized on $@ array
23set -- 1a 2a 3a
24argv.py ${@%a}
25## stdout: ['1', '2', '3']
26## status: 0
27## N-I dash/ash stdout: ['1a', '2a', '3']
28## N-I dash/ash status: 0
29## N-I mksh stdout-json: ""
30## N-I mksh status: 1
31
32#### Remove const suffix from undefined
33echo ${undef%suffix}
34## stdout:
35
36#### Remove shortest glob suffix
37v=aabbccdd
38echo ${v%c*}
39## stdout: aabbc
40
41#### Remove longest glob suffix
42v=aabbccdd
43echo ${v%%c*}
44## stdout: aabb
45
46#### Remove shortest glob prefix
47v=aabbccdd
48echo ${v#*b}
49## stdout: bccdd
50
51#### Remove longest glob prefix
52v=aabbccdd
53echo ${v##*b}
54## stdout: ccdd
55
56#### Strip char class
57v=abc
58echo ${v%[[:alpha:]]}
59## stdout: ab
60## N-I mksh stdout: abc
61
62#### Strip unicode prefix
63
64show_hex() { od -A n -t c -t x1; }
65
66# NOTE: LANG is set to utf-8.
67# ? is a glob that stands for one character
68
69v='μ-'
70echo ${v#?} | show_hex
71echo
72echo ${v##?} | show_hex
73echo
74
75v=''
76echo ${v%?} | show_hex
77echo
78echo ${v%%?} | show_hex
79## STDOUT:
80 - \n
81 2d 0a
82
83 - \n
84 2d 0a
85
86 - \n
87 2d 0a
88
89 - \n
90 2d 0a
91## BUG dash/mksh/ash STDOUT:
92 274 - \n
93 bc 2d 0a
94
95 274 - \n
96 bc 2d 0a
97
98 - 316 \n
99 2d ce 0a
100
101 - 316 \n
102 2d ce 0a
103## END
104## BUG-2 zsh STDOUT:
105 \n
106 0a
107
108 \n
109 0a
110
111 \n
112 0a
113
114 \n
115 0a
116## END
117
118#### Bug fix: Test that you can remove everything with glob
119s='--x--'
120argv.py "${s%%-*}" "${s%-*}" "${s#*-}" "${s##*-}"
121## STDOUT:
122['', '--x-', '-x--', '']
123## END
124
125#### Test that you can remove everything with const
126s='abcd'
127argv.py "${s%%abcd}" "${s%abcd}" "${s#abcd}" "${s##abcd}"
128# failure case:
129argv.py "${s%%abcde}" "${s%abcde}" "${s#abcde}" "${s##abcde}"
130## STDOUT:
131['', '', '', '']
132['abcd', 'abcd', 'abcd', 'abcd']
133## END
134
135#### Prepend using replacement of #
136# This case was found in Kubernetes and others
137array=(aa bb '')
138argv.py ${array[@]/#/prefix-}
139## STDOUT:
140['prefix-aa', 'prefix-bb', 'prefix-']
141## END
142## N-I dash/ash status: 2
143## N-I dash/ash stdout-json: ""
144## N-I mksh status: 1
145## N-I mksh stdout-json: ""
146
147#### Append using replacement of %
148array=(aa bb '')
149argv.py ${array[@]/%/-suffix}
150## STDOUT:
151['aa-suffix', 'bb-suffix', '-suffix']
152## END
153## N-I dash/ash status: 2
154## N-I dash/ash stdout-json: ""
155## N-I mksh status: 1
156## N-I mksh stdout-json: ""
157
158#### strip unquoted and quoted [
159# I guess dash and mksh treat unquoted [ as an invalid glob?
160var='[foo]'
161echo ${var#[}
162echo ${var#"["}
163echo "${var#[}"
164echo "${var#"["}"
165## STDOUT:
166foo]
167foo]
168foo]
169foo]
170## END
171## OK mksh STDOUT:
172[foo]
173foo]
174[foo]
175foo]
176## END
177## BUG zsh stdout-json: ""
178## BUG zsh status: 1
179
180#### strip unquoted and quoted []
181# LooksLikeGlob('[]') is true
182# I guess dash, mksh, and zsh treat unquoted [ as an invalid glob?
183var='[]foo[]'
184echo ${var#[]}
185echo ${var#"[]"}
186echo "${var#[]}"
187echo "${var#"[]"}"
188## STDOUT:
189foo[]
190foo[]
191foo[]
192foo[]
193## END
194## OK mksh/zsh STDOUT:
195[]foo[]
196foo[]
197[]foo[]
198foo[]
199## END
200
201#### strip unquoted and quoted ?
202var='[foo]'
203echo ${var#?}
204echo ${var#"?"}
205echo "${var#?}"
206echo "${var#"?"}"
207## STDOUT:
208foo]
209[foo]
210foo]
211[foo]
212## END
213
214#### strip unquoted and quoted [a]
215var='[a]foo[]'
216echo ${var#[a]}
217echo ${var#"[a]"}
218echo "${var#[a]}"
219echo "${var#"[a]"}"
220## STDOUT:
221[a]foo[]
222foo[]
223[a]foo[]
224foo[]
225## END
226
227#### Nested % and # operators (bug reported by Crestwave)
228var=$'\n'
229argv.py "${var#?}"
230argv.py "${var%''}"
231argv.py "${var%"${var#?}"}"
232var='a'
233argv.py "${var#?}"
234argv.py "${var%''}"
235argv.py "${var%"${var#?}"}"
236## STDOUT:
237['']
238['\n']
239['\n']
240['']
241['a']
242['a']
243## END
244## N-I dash STDOUT:
245['\\n']
246['$\\n']
247['$']
248['']
249['a']
250['a']
251## END
252
253#### strip * (bug regression)
254x=abc
255argv.py "${x#*}"
256argv.py "${x##*}"
257argv.py "${x%*}"
258argv.py "${x%%*}"
259## STDOUT:
260['abc']
261['']
262['abc']
263['']
264## END
265## BUG zsh STDOUT:
266['abc']
267['']
268['ab']
269['']
270## END
271
272#### strip ?
273x=abc
274argv.py "${x#?}"
275argv.py "${x##?}"
276argv.py "${x%?}"
277argv.py "${x%%?}"
278## STDOUT:
279['bc']
280['bc']
281['ab']
282['ab']
283## END
284
285#### strip all
286x=abc
287argv.py "${x#abc}"
288argv.py "${x##abc}"
289argv.py "${x%abc}"
290argv.py "${x%%abc}"
291## STDOUT:
292['']
293['']
294['']
295['']
296## END
297
298#### strip none
299x=abc
300argv.py "${x#}"
301argv.py "${x##}"
302argv.py "${x%}"
303argv.py "${x%%}"
304## STDOUT:
305['abc']
306['abc']
307['abc']
308['abc']
309## END
310
311#### strip all unicode
312x=μabcμ
313echo "${x#?abc?}"
314echo "${x##?abc?}"
315echo "${x%?abc?}"
316echo "${x%%?abc?}"
317## STDOUT:
318
319
320
321
322## BUG dash/mksh/ash STDOUT:
323μabcμ
324μabcμ
325μabcμ
326μabcμ
327## END
328
329#### strip none unicode
330x=μabcμ
331argv.py "${x#}"
332argv.py "${x##}"
333argv.py "${x%}"
334argv.py "${x%%}"
335## STDOUT:
336['\xce\xbcabc\xce\xbc']
337['\xce\xbcabc\xce\xbc']
338['\xce\xbcabc\xce\xbc']
339['\xce\xbcabc\xce\xbc']
340## END
341
342#### Strip Right Brace (#702)
343var='$foo'
344echo 1 "${var#$foo}"
345echo 2 "${var#\$foo}"
346
347var='}'
348echo 10 "${var#}}"
349echo 11 "${var#\}}"
350echo 12 "${var#'}'}"
351echo 13 "${var#"}"}"
352## STDOUT:
3531 $foo
3542
35510 }}
35611
35712
35813
359## END
360## BUG zsh STDOUT:
3611 $foo
3622
36310 }}
36411
36512 }'}
36613
367## END
368
369#### \(\) in pattern (regression)
370x='foo()'
371echo 1 ${x%*\(\)}
372echo 2 ${x%%*\(\)}
373echo 3 ${x#*\(\)}
374echo 4 ${x##*\(\)}
375## STDOUT:
3761 foo
3772
3783
3794
380## END
381
382#### extglob in pattern
383case $SH in dash|zsh|ash) exit ;; esac
384
385shopt -s extglob
386
387x='foo()'
388echo 1 ${x%*(foo|bar)'()'}
389echo 2 ${x%%*(foo|bar)'()'}
390echo 3 ${x#*(foo|bar)'()'}
391echo 4 ${x##*(foo|bar)'()'}
392## STDOUT:
3931 foo
3942
3953
3964
397## END
398## N-I dash/zsh/ash stdout-json: ""