1 |
#!/bin/bash |
2 |
# |
3 |
# Test ${x/pat*/replace} |
4 |
|
5 |
#### Pattern replacement |
6 |
v=abcde |
7 |
echo ${v/c*/XX} |
8 |
## stdout: abXX |
9 |
|
10 |
#### Pattern replacement on unset variable |
11 |
echo -${v/x/y}- |
12 |
echo status=$? |
13 |
set -o nounset # make sure this fails |
14 |
echo -${v/x/y}- |
15 |
## STDOUT: |
16 |
-- |
17 |
status=0 |
18 |
## BUG mksh STDOUT: |
19 |
# patsub disrespects nounset! |
20 |
-- |
21 |
status=0 |
22 |
-- |
23 |
## status: 1 |
24 |
## BUG mksh status: 0 |
25 |
|
26 |
#### Global Pattern replacement with / |
27 |
s=xx_xx_xx |
28 |
echo ${s/xx?/yy_} ${s//xx?/yy_} |
29 |
## stdout: yy_xx_xx yy_yy_xx |
30 |
|
31 |
#### Left Anchored Pattern replacement with # |
32 |
s=xx_xx_xx |
33 |
echo ${s/?xx/_yy} ${s/#?xx/_yy} |
34 |
## stdout: xx_yy_xx xx_xx_xx |
35 |
|
36 |
#### Right Anchored Pattern replacement with % |
37 |
s=xx_xx_xx |
38 |
echo ${s/?xx/_yy} ${s/%?xx/_yy} |
39 |
## stdout: xx_yy_xx xx_xx_yy |
40 |
|
41 |
#### Replace fixed strings |
42 |
s=xx_xx |
43 |
echo ${s/xx/yy} ${s//xx/yy} ${s/#xx/yy} ${s/%xx/yy} |
44 |
## stdout: yy_xx yy_yy yy_xx xx_yy |
45 |
|
46 |
#### Replace is longest match |
47 |
# If it were shortest, then you would just replace the first <html> |
48 |
s='begin <html></html> end' |
49 |
echo ${s/<*>/[]} |
50 |
## stdout: begin [] end |
51 |
|
52 |
#### Replace char class |
53 |
s=xx_xx_xx |
54 |
echo ${s//[[:alpha:]]/y} ${s//[^[:alpha:]]/-} |
55 |
## stdout: yy_yy_yy xx-xx-xx |
56 |
## N-I mksh stdout: xx_xx_xx xx_xx_xx |
57 |
|
58 |
#### Replace hard glob |
59 |
s='aa*bb+cc' |
60 |
echo ${s//\**+/__} # Literal *, then any sequence of characters, then literal + |
61 |
## stdout: aa__cc |
62 |
|
63 |
#### Pattern replacement ${v/} is not valid |
64 |
v=abcde |
65 |
echo -${v/}- |
66 |
echo status=$? |
67 |
## status: 2 |
68 |
## stdout-json: "" |
69 |
## BUG bash/mksh/zsh status: 0 |
70 |
## BUG bash/mksh/zsh STDOUT: |
71 |
-abcde- |
72 |
status=0 |
73 |
## END |
74 |
|
75 |
#### Pattern replacement ${v//} is not valid |
76 |
v='a/b/c' |
77 |
echo -${v//}- |
78 |
echo status=$? |
79 |
## status: 2 |
80 |
## stdout-json: "" |
81 |
## BUG bash/mksh/zsh status: 0 |
82 |
## BUG bash/mksh/zsh STDOUT: |
83 |
-a/b/c- |
84 |
status=0 |
85 |
## END |
86 |
|
87 |
#### ${v/a} is the same as ${v/a/} -- no replacement string |
88 |
v='aabb' |
89 |
echo ${v/a} |
90 |
echo status=$? |
91 |
## STDOUT: |
92 |
abb |
93 |
status=0 |
94 |
## END |
95 |
|
96 |
#### Replacement with special chars (bug fix) |
97 |
v=xx |
98 |
echo ${v/x/"?"} |
99 |
## stdout: ?x |
100 |
|
101 |
#### Replace backslash |
102 |
v='[\f]' |
103 |
x='\f' |
104 |
echo ${v/"$x"/_} |
105 |
|
106 |
# mksh and zsh differ on this case, but this is consistent with the fact that |
107 |
# \f as a glob means 'f', not '\f'. TODO: Warn that it's a bad glob? |
108 |
# The canonical form is 'f'. |
109 |
echo ${v/$x/_} |
110 |
|
111 |
echo ${v/\f/_} |
112 |
echo ${v/\\f/_} |
113 |
## STDOUT: |
114 |
[_] |
115 |
[\_] |
116 |
[\_] |
117 |
[_] |
118 |
## END |
119 |
## BUG mksh/zsh STDOUT: |
120 |
[_] |
121 |
[_] |
122 |
[\_] |
123 |
[_] |
124 |
## END |
125 |
|
126 |
#### Replace right ] |
127 |
v='--]--' |
128 |
x=']' |
129 |
echo ${v/"$x"/_} |
130 |
echo ${v/$x/_} |
131 |
## STDOUT: |
132 |
--_-- |
133 |
--_-- |
134 |
## END |
135 |
|
136 |
#### Substitute glob characters in pattern, quoted and unquoted |
137 |
g='*' |
138 |
v='a*b' |
139 |
echo ${v//"$g"/-} |
140 |
echo ${v//$g/-} |
141 |
## STDOUT: |
142 |
a-b |
143 |
- |
144 |
## END |
145 |
## BUG zsh STDOUT: |
146 |
a-b |
147 |
a-b |
148 |
## END |