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