1 |
# |
2 |
# Test ${x/pat*/replace} |
3 |
|
4 |
#### Pattern replacement |
5 |
v=abcde |
6 |
echo ${v/c*/XX} |
7 |
## stdout: abXX |
8 |
|
9 |
#### Pattern replacement on unset variable |
10 |
echo -${v/x/y}- |
11 |
echo status=$? |
12 |
set -o nounset # make sure this fails |
13 |
echo -${v/x/y}- |
14 |
## STDOUT: |
15 |
-- |
16 |
status=0 |
17 |
## BUG mksh STDOUT: |
18 |
# patsub disrespects nounset! |
19 |
-- |
20 |
status=0 |
21 |
-- |
22 |
## status: 1 |
23 |
## BUG mksh status: 0 |
24 |
|
25 |
#### Global Pattern replacement with / |
26 |
s=xx_xx_xx |
27 |
echo ${s/xx?/yy_} ${s//xx?/yy_} |
28 |
## stdout: yy_xx_xx yy_yy_xx |
29 |
|
30 |
#### Left Anchored Pattern replacement with # |
31 |
s=xx_xx_xx |
32 |
echo ${s/?xx/_yy} ${s/#?xx/_yy} |
33 |
## stdout: xx_yy_xx xx_xx_xx |
34 |
|
35 |
#### Right Anchored Pattern replacement with % |
36 |
s=xx_xx_xx |
37 |
echo ${s/?xx/_yy} ${s/%?xx/_yy} |
38 |
## stdout: xx_yy_xx xx_xx_yy |
39 |
|
40 |
#### Replace fixed strings |
41 |
s=xx_xx |
42 |
echo ${s/xx/yy} ${s//xx/yy} ${s/#xx/yy} ${s/%xx/yy} |
43 |
## stdout: yy_xx yy_yy yy_xx xx_yy |
44 |
|
45 |
#### Replace is longest match |
46 |
# If it were shortest, then you would just replace the first <html> |
47 |
s='begin <html></html> end' |
48 |
echo ${s/<*>/[]} |
49 |
## stdout: begin [] end |
50 |
|
51 |
#### Replace char class |
52 |
s=xx_xx_xx |
53 |
echo ${s//[[:alpha:]]/y} ${s//[^[:alpha:]]/-} |
54 |
## stdout: yy_yy_yy xx-xx-xx |
55 |
## N-I mksh stdout: xx_xx_xx xx_xx_xx |
56 |
|
57 |
#### Replace hard glob |
58 |
s='aa*bb+cc' |
59 |
echo ${s//\**+/__} # Literal *, then any sequence of characters, then literal + |
60 |
## stdout: aa__cc |
61 |
|
62 |
#### Pattern replacement ${v/} is not valid |
63 |
v=abcde |
64 |
echo -${v/}- |
65 |
echo status=$? |
66 |
## status: 2 |
67 |
## stdout-json: "" |
68 |
## BUG bash/mksh/zsh status: 0 |
69 |
## BUG bash/mksh/zsh STDOUT: |
70 |
-abcde- |
71 |
status=0 |
72 |
## END |
73 |
|
74 |
#### Pattern replacement ${v//} is not valid |
75 |
v='a/b/c' |
76 |
echo -${v//}- |
77 |
echo status=$? |
78 |
## status: 2 |
79 |
## stdout-json: "" |
80 |
## BUG bash/mksh/zsh status: 0 |
81 |
## BUG bash/mksh/zsh STDOUT: |
82 |
-a/b/c- |
83 |
status=0 |
84 |
## END |
85 |
|
86 |
#### Confusing unquoted slash matches bash (and ash) |
87 |
x='/_/' |
88 |
echo ${x////c} |
89 |
echo ${x//'/'/c} |
90 |
## STDOUT: |
91 |
c_c |
92 |
c_c |
93 |
## END |
94 |
## BUG mksh/yash STDOUT: |
95 |
/_/ |
96 |
c_c |
97 |
## END |
98 |
## BUG zsh STDOUT: |
99 |
/c//c_/c/ |
100 |
/_/ |
101 |
## END |
102 |
## BUG ash STDOUT: |
103 |
c_c |
104 |
/_/ |
105 |
## END |
106 |
|
107 |
#### ${v/a} is the same as ${v/a/} -- no replacement string |
108 |
v='aabb' |
109 |
echo ${v/a} |
110 |
echo status=$? |
111 |
## STDOUT: |
112 |
abb |
113 |
status=0 |
114 |
## END |
115 |
|
116 |
#### Replacement with special chars (bug fix) |
117 |
v=xx |
118 |
echo ${v/x/"?"} |
119 |
## stdout: ?x |
120 |
|
121 |
#### Replace backslash |
122 |
v='[\f]' |
123 |
x='\f' |
124 |
echo ${v/"$x"/_} |
125 |
|
126 |
# mksh and zsh differ on this case, but this is consistent with the fact that |
127 |
# \f as a glob means 'f', not '\f'. TODO: Warn that it's a bad glob? |
128 |
# The canonical form is 'f'. |
129 |
echo ${v/$x/_} |
130 |
|
131 |
echo ${v/\f/_} |
132 |
echo ${v/\\f/_} |
133 |
## STDOUT: |
134 |
[_] |
135 |
[\_] |
136 |
[\_] |
137 |
[_] |
138 |
## END |
139 |
## BUG mksh/zsh STDOUT: |
140 |
[_] |
141 |
[_] |
142 |
[\_] |
143 |
[_] |
144 |
## END |
145 |
|
146 |
#### Replace right ] |
147 |
v='--]--' |
148 |
x=']' |
149 |
echo ${v/"$x"/_} |
150 |
echo ${v/$x/_} |
151 |
## STDOUT: |
152 |
--_-- |
153 |
--_-- |
154 |
## END |
155 |
|
156 |
#### Substitute glob characters in pattern, quoted and unquoted |
157 |
g='*' |
158 |
v='a*b' |
159 |
echo ${v//"$g"/-} |
160 |
echo ${v//$g/-} |
161 |
## STDOUT: |
162 |
a-b |
163 |
- |
164 |
## END |
165 |
## BUG zsh STDOUT: |
166 |
a-b |
167 |
a-b |
168 |
## END |
169 |
|
170 |
#### Substitute one unicode character (UTF-8) |
171 |
export LANG='en_US.UTF-8' |
172 |
|
173 |
s='_μ_ and _μ_' |
174 |
|
175 |
# ? should match one char |
176 |
|
177 |
echo ${s//_?_/foo} # all |
178 |
echo ${s/#_?_/foo} # left |
179 |
echo ${s/%_?_/foo} # right |
180 |
|
181 |
## STDOUT: |
182 |
foo and foo |
183 |
foo and _μ_ |
184 |
_μ_ and foo |
185 |
## END |
186 |
## BUG mksh STDOUT: |
187 |
_μ_ and _μ_ |
188 |
_μ_ and _μ_ |
189 |
_μ_ and _μ_ |
190 |
## END |
191 |
|
192 |
#### Can't substitute one unicode character when LC_ALL=C |
193 |
export LC_ALL='C' |
194 |
|
195 |
s='_μ_ and _μ_' |
196 |
|
197 |
# ? should match one char |
198 |
|
199 |
echo ${s//_?_/foo} # all |
200 |
echo ${s/#_?_/foo} # left |
201 |
echo ${s/%_?_/foo} # right |
202 |
|
203 |
## STDOUT: |
204 |
_μ_ and _μ_ |
205 |
_μ_ and _μ_ |
206 |
_μ_ and _μ_ |
207 |
## END |
208 |
|
209 |
#### ${x/^} regression |
210 |
x=abc |
211 |
echo ${x/^} |
212 |
echo ${x/!} |
213 |
|
214 |
y=^^^ |
215 |
echo ${y/^} |
216 |
echo ${y/!} |
217 |
|
218 |
z=!!! |
219 |
echo ${z/^} |
220 |
echo ${z/!} |
221 |
|
222 |
s=a^b!c |
223 |
echo ${s/a^} |
224 |
echo ${s/b!} |
225 |
|
226 |
## STDOUT: |
227 |
abc |
228 |
abc |
229 |
^^ |
230 |
^^^ |
231 |
!!! |
232 |
!! |
233 |
b!c |
234 |
a^c |
235 |
## END |
236 |
|
237 |
#### \(\) in pattern (regression) |
238 |
|
239 |
# Not extended globs |
240 |
x='foo()' |
241 |
echo 1 ${x//*\(\)/z} |
242 |
echo 2 ${x//*\(\)/z} |
243 |
echo 3 ${x//\(\)/z} |
244 |
echo 4 ${x//*\(\)/z} |
245 |
|
246 |
## STDOUT: |
247 |
1 z |
248 |
2 z |
249 |
3 fooz |
250 |
4 z |
251 |
## END |
252 |
|
253 |
#### patsub with single quotes and hyphen in character class (regression) |
254 |
|
255 |
# from Crestwave's bf.bash |
256 |
|
257 |
program='^++--hello.,world<>[]' |
258 |
program=${program//[^'><+-.,[]']} |
259 |
echo $program |
260 |
## STDOUT: |
261 |
++--.,<>[] |
262 |
## END |
263 |
## BUG mksh STDOUT: |
264 |
helloworld |
265 |
## END |
266 |
|
267 |
#### patsub with [^]] |
268 |
|
269 |
# This is a PARSING divergence. In Oil we match [], rather than using POSIX |
270 |
# rules! |
271 |
|
272 |
pat='[^]]' |
273 |
s='ab^cd^' |
274 |
echo ${s//$pat/z} |
275 |
## STDOUT: |
276 |
ab^cd^ |
277 |
## END |
278 |
|
279 |
#### patsub syntax error |
280 |
x=fooz |
281 |
pat='[z-a]' # Invalid range. Other shells don't catch it! |
282 |
#pat='[a-y]' |
283 |
echo ${x//$pat} |
284 |
echo status=$? |
285 |
## stdout-json: "" |
286 |
## status: 1 |
287 |
## OK bash/mksh/zsh STDOUT: |
288 |
fooz |
289 |
status=0 |
290 |
## END |
291 |
## OK bash/mksh/zsh status: 0 |