Gentoo Archives: gentoo-user

From: gentuxx <gentuxx@×××××.com>
To: gentoo-user@l.g.o
Subject: Re: [gentoo-user] About sed
Date: Mon, 07 Nov 2005 06:42:13
Message-Id: 436EF641.2060807@gmail.com
In Reply to: Re: [gentoo-user] About sed by Rafael Barreto
1 -----BEGIN PGP SIGNED MESSAGE-----
2 Hash: SHA1
3
4 Rafael Barreto wrote:
5
6 > Other thing... Why was necessary to ^CLOCK= before
7 s/^\(CLOCK=".*"\).*$/\1/p? And which the necessity of the ( ) between
8 the regular expression?
9 >
10 > Thanks again
11 >
12
13 Sorry for things being out of order, but you top-posted. The answer
14 to your first question is below.
15
16 The /^CLOCK=/ is NOT necessary, in this instance, and may actually
17 cause problems if you're not 100% sure of your regular expression. It
18 is there, simply because I was expanding your original pattern. What
19 this does, though, is it tells sed to match the line with the regular
20 expression before making any substitutions and/or replacements. Say
21 for example, you had 2 lines in the same file with different values
22 but similar structure, and you only wanted to change one of them.
23 Let's go with the example you used. Let's assume that our example
24 file looks something like this:
25
26 # This is a comment
27 CLOCK="foo1"
28 # This is another comment
29 TIMEZONE="GMT"
30 # This is yet another comment
31 CLOCK="${CLOCK}foo2"
32
33 So, let's say that you wanted to change the second instance. The
34 /^CLOCK=/ tells sed to ignore all lines that do NOT begin with
35 'CLOCK='. So the comments ( # This is a comment ) and the 'TIMEZONE'
36 directive will be ignored. Actions will only be taken on the lines:
37
38 CLOCK="foo1"
39 CLOCK="${CLOCK}foo2"
40
41 ...because they match the expression we gave sed as an "address" (
42 /^CLOCK=/ ). We would furthur specify how to change that line by our
43 search and replace command (as described below):
44
45 s/^\(CLOCK=\"\)\${.*}\(\".*\)$/\1foo3\2/
46
47
48
49 It is important to note here that the left and right brace characters
50 ( { } ) are not escaped. If they were, they would have been handled
51 as metacharacters, which produces a drastically different result.
52
53 If you really want to get to know sed (and awk), I HIGHLY recommend
54 getting the 2 O'reilley books: Sed & Awk, and Mastering Regular
55 Expressions. Both of these two books have taught me almost everything
56 I know on the matter, and I refer to them frequently.
57
58 HTH
59
60
61 > 2005/11/7, Rafael Barreto <rafaelmbarreto@×××××.com
62 <mailto:rafaelmbarreto@×××××.com>>:
63 >
64 > For that I understood, this command will return the line of CLOCK= in
65 /etc/conf.f/clock without any comments. Is this right? Well, what I
66 really want is replace just CLOCK="fool1" by CLOCK="fool2" keeping the
67 comments in line.
68 >
69 > By the way, \1 do really what? If i put \0 the result is the entire
70 line. So, could you explain me this a little more? Thanks...
71 >
72 > 2005/11/7, gentuxx < gentuxx@×××××.com <mailto:gentuxx@×××××.com>>:
73 >
74
75 I will try to answer both of your questions with this one email.
76
77 The '\1' takes the first element, or element group, captured by the
78 parentheses metacharacters ( \( \) ) and uses it as a variable. The
79 variable '\0', as you found out, represents the entire contents of the
80 "pattern space" or basically, the entire line since you're matching
81 beginning ( ^ ) to end ( $ ). The variable '\0' is also synonymous
82 with the ampersand metacharacter ( & ). So, if you want to change the
83 value of the "CLOCK" variable in /etc/conf.d/clock, while leaving any
84 comments intact, you could do something like this:
85
86 sed 's/^\(CLOCK=\"\).*\(\".*\)$/\1foo2\2/' /etc/conf.d/clock
87
88 This matches and captures the contents of the first set of
89 parentheses, and places it into a variable accessible by '\1'. Then
90 it matches 0 or more of any character type, until it matches a literal
91 double-quote ( \" ). Then it matches and captures the contents of the
92 second set of parentheses, and places it into a variable accessible by
93 '\2'. So, to change the value, you would issue a substitution command
94 ( s/// ) which matches the first set and replaces it with the second
95 set. The variables '\1' and '\2' are interpolated, so the values
96 captured are printed. I.e. the result should be:
97
98 was:
99 CLOCK="foo1" # some comments here
100
101 now:
102 CLOCK="foo2" # some comments here
103
104
105
106 > Willie Wong wrote:
107 >
108 > >>On Mon, Nov 07, 2005 at 01:44:42AM -0200, Rafael Barreto wrote:
109 > >>
110 > >>>Hi,
111 > >>>
112 > >>>I'm learning about the use of the sed command and I have some
113 > questions. I'm
114 > >>>trying to read in /etc/conf.d/clock the CLOCK variable with:
115 > >>>
116 > >>>sed '/^CLOCK="*"$/p' /etc/conf.d/clock
117 > >>>
118 > >>>This command, in principe, must print in screen the line that
119 > contains
120 > >>>CLOCK= in the begin, contains anything between double quotes and
121 > ends.
122 > Well,
123 > >>>this doesn't return anything. If I enter the above command without $,
124 > all is
125 > >>>ok. But, if I would like to return just that line contains
126 > CLOCK="anything"
127 > >>>and nothing more? For example,
128 > >>
129 > >>
130 > >>No it doesn't. What you want is the regexp ^CLOCK=".*"$ if you want
131 > >>anything (including nothing) between the double quotes, or
132 > >>^CLOCK=".+"$ if you want something (excluding nothing) between the
133 > >>double quotes.
134 > >>
135 > >>The reason that removing the trailing $ worked is that it matched the
136 > >>CLOCK=" part, the * character specifies 0 or more iterates of the
137 > >>previous character, which is "
138 > >>
139 > >>HTH
140 > >>
141 > >>W
142 >
143 > Also, as you pointed out, lines with trailing comments would not be
144 > returned based on the expression (even as modified):
145 >
146 > sed '/^CLOCK=".*"$/p /etc/conf.d/clock
147 >
148 > This is because the expression, as is, does not allow for anything
149 > after the last double quote ("). The following expression should
150 > match the line you want, and print out ONLY the 'CLOCK="foo"':
151 >
152 > sed -n '/^CLOCK=/s/^\(CLOCK=".*"\).*$/\1/p /etc/conf.d/clock
153 >
154 > How this works is as follows (since you're trying to learn sed):
155 >
156 > 1) the '-n' suppresses all output except that which was changed by
157 > your expression/commands.
158 > 2) the first expression ( /^CLOCK=/ ) gives sed the "address" at which
159 > to make the changes.
160 > 3) the second expression ( s/^\(CLOCK=".*"\).*$/\1/p )tells sed what
161 > to do when it reaches that address. This is better broken down into
162 > smaller steps:
163 > a) the first half of the substitution expression (
164 > s/^\(CLOCK=".*"\).*$/ ) tells sed to match the capital letters C
165 > -L-O-C-K which start a line ( ^ ),
166 > b) followed by an equals sign (=), a double-quote ("),
167 > c) followed by 0 or more of any character type - except newlines
168 > - ( .* ),
169 > d) followed by another double-quote (").
170 > e) Then, because of the parentheses metacharacters ( \( \) ),
171 > store the match in the holding space (memory).
172 > f) Then match 0 or more of any character type ( .* ), ending the
173 > line ( $ ).
174 > g) the second half ( /\1/ ) substitutes the characters "captured"
175 > in the parentheses metacharacters, for the whole line
176 > h) and prints ( /p ) the result
177 >
178 > So, while Willie's suggestion is correct, this should give you a more
179 > complete solution.
180 >
181 > HTH
182 >
183 > --
184 > gentux
185 > echo "hfouvyAdpy/ofu" | perl -pe 's/(.)/chr(ord($1)-1)/ge'
186 >
187 > gentux's gpg fingerprint ==> 34CE 2E97 40C7 EF6E EC40 9795 2D81 924A
188 > 6996 0993
189
190
191 - --
192 gentoo-user@g.o <mailto:gentoo-user@g.o> mailing list
193
194
195
196
197
198 - --
199 gentux
200 echo "hfouvyAdpy/ofu" | perl -pe 's/(.)/chr(ord($1)-1)/ge'
201
202 gentux's gpg fingerprint ==> 34CE 2E97 40C7 EF6E EC40 9795 2D81 924A
203 6996 0993
204 -----BEGIN PGP SIGNATURE-----
205 Version: GnuPG v1.4.1 (GNU/Linux)
206
207 iD8DBQFDbvZBLYGSSmmWCZMRAu2TAJ9QluvFRh2Hvu2T1p6DxOkhsD+gUgCgvYjC
208 qQ12BqJsAQHxMEfBkLTodAw=
209 =LvhF
210 -----END PGP SIGNATURE-----
211
212 --
213 gentoo-user@g.o mailing list

Replies

Subject Author
Re: [gentoo-user] [OT] About sed Willie Wong <wwong@×××××××××.EDU>