-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Rafael Barreto wrote:
> Other thing... Why was necessary to ^CLOCK= before s/^\(CLOCK=".*"\).*$/\1/p? And which the necessity of the ( ) between the regular expression? > > Thanks again > Sorry for things being out of order, but you top-posted. The answer to your first question is below. The /^CLOCK=/ is NOT necessary, in this instance, and may actually cause problems if you're not 100% sure of your regular expression. It is there, simply because I was expanding your original pattern. What this does, though, is it tells sed to match the line with the regular expression before making any substitutions and/or replacements. Say for example, you had 2 lines in the same file with different values but similar structure, and you only wanted to change one of them. Let's go with the example you used. Let's assume that our example file looks something like this: # This is a comment CLOCK="foo1" # This is another comment TIMEZONE="GMT" # This is yet another comment CLOCK="${CLOCK}foo2" So, let's say that you wanted to change the second instance. The /^CLOCK=/ tells sed to ignore all lines that do NOT begin with 'CLOCK='. So the comments ( # This is a comment ) and the 'TIMEZONE' directive will be ignored. Actions will only be taken on the lines: CLOCK="foo1" CLOCK="${CLOCK}foo2" ...because they match the expression we gave sed as an "address" ( /^CLOCK=/ ). We would furthur specify how to change that line by our search and replace command (as described below): s/^\(CLOCK=\"\)\${.*}\(\".*\)$/\1foo3\2/ It is important to note here that the left and right brace characters ( { } ) are not escaped. If they were, they would have been handled as metacharacters, which produces a drastically different result. If you really want to get to know sed (and awk), I HIGHLY recommend getting the 2 O'reilley books: Sed & Awk, and Mastering Regular Expressions. Both of these two books have taught me almost everything I know on the matter, and I refer to them frequently. HTH > 2005/11/7, Rafael Barreto <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>: > > For that I understood, this command will return the line of CLOCK= in /etc/conf.f/clock without any comments. Is this right? Well, what I really want is replace just CLOCK="fool1" by CLOCK="fool2" keeping the comments in line. > > By the way, \1 do really what? If i put \0 the result is the entire line. So, could you explain me this a little more? Thanks... > > 2005/11/7, gentuxx < [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>: > I will try to answer both of your questions with this one email. The '\1' takes the first element, or element group, captured by the parentheses metacharacters ( \( \) ) and uses it as a variable. The variable '\0', as you found out, represents the entire contents of the "pattern space" or basically, the entire line since you're matching beginning ( ^ ) to end ( $ ). The variable '\0' is also synonymous with the ampersand metacharacter ( & ). So, if you want to change the value of the "CLOCK" variable in /etc/conf.d/clock, while leaving any comments intact, you could do something like this: sed 's/^\(CLOCK=\"\).*\(\".*\)$/\1foo2\2/' /etc/conf.d/clock This matches and captures the contents of the first set of parentheses, and places it into a variable accessible by '\1'. Then it matches 0 or more of any character type, until it matches a literal double-quote ( \" ). Then it matches and captures the contents of the second set of parentheses, and places it into a variable accessible by '\2'. So, to change the value, you would issue a substitution command ( s/// ) which matches the first set and replaces it with the second set. The variables '\1' and '\2' are interpolated, so the values captured are printed. I.e. the result should be: was: CLOCK="foo1" # some comments here now: CLOCK="foo2" # some comments here > Willie Wong wrote: > > >>On Mon, Nov 07, 2005 at 01:44:42AM -0200, Rafael Barreto wrote: > >> > >>>Hi, > >>> > >>>I'm learning about the use of the sed command and I have some > questions. I'm > >>>trying to read in /etc/conf.d/clock the CLOCK variable with: > >>> > >>>sed '/^CLOCK="*"$/p' /etc/conf.d/clock > >>> > >>>This command, in principe, must print in screen the line that > contains > >>>CLOCK= in the begin, contains anything between double quotes and > ends. > Well, > >>>this doesn't return anything. If I enter the above command without $, > all is > >>>ok. But, if I would like to return just that line contains > CLOCK="anything" > >>>and nothing more? For example, > >> > >> > >>No it doesn't. What you want is the regexp ^CLOCK=".*"$ if you want > >>anything (including nothing) between the double quotes, or > >>^CLOCK=".+"$ if you want something (excluding nothing) between the > >>double quotes. > >> > >>The reason that removing the trailing $ worked is that it matched the > >>CLOCK=" part, the * character specifies 0 or more iterates of the > >>previous character, which is " > >> > >>HTH > >> > >>W > > Also, as you pointed out, lines with trailing comments would not be > returned based on the expression (even as modified): > > sed '/^CLOCK=".*"$/p /etc/conf.d/clock > > This is because the expression, as is, does not allow for anything > after the last double quote ("). The following expression should > match the line you want, and print out ONLY the 'CLOCK="foo"': > > sed -n '/^CLOCK=/s/^\(CLOCK=".*"\).*$/\1/p /etc/conf.d/clock > > How this works is as follows (since you're trying to learn sed): > > 1) the '-n' suppresses all output except that which was changed by > your expression/commands. > 2) the first expression ( /^CLOCK=/ ) gives sed the "address" at which > to make the changes. > 3) the second expression ( s/^\(CLOCK=".*"\).*$/\1/p )tells sed what > to do when it reaches that address. This is better broken down into > smaller steps: > a) the first half of the substitution expression ( > s/^\(CLOCK=".*"\).*$/ ) tells sed to match the capital letters C > -L-O-C-K which start a line ( ^ ), > b) followed by an equals sign (=), a double-quote ("), > c) followed by 0 or more of any character type - except newlines > - ( .* ), > d) followed by another double-quote ("). > e) Then, because of the parentheses metacharacters ( \( \) ), > store the match in the holding space (memory). > f) Then match 0 or more of any character type ( .* ), ending the > line ( $ ). > g) the second half ( /\1/ ) substitutes the characters "captured" > in the parentheses metacharacters, for the whole line > h) and prints ( /p ) the result > > So, while Willie's suggestion is correct, this should give you a more > complete solution. > > HTH > > -- > gentux > echo "hfouvyAdpy/ofu" | perl -pe 's/(.)/chr(ord($1)-1)/ge' > > gentux's gpg fingerprint ==> 34CE 2E97 40C7 EF6E EC40 9795 2D81 924A > 6996 0993 - -- gentoo-user@gentoo.org <mailto:gentoo-user@gentoo.org> mailing list - -- gentux echo "hfouvyAdpy/ofu" | perl -pe 's/(.)/chr(ord($1)-1)/ge' gentux's gpg fingerprint ==> 34CE 2E97 40C7 EF6E EC40 9795 2D81 924A 6996 0993 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFDbvZBLYGSSmmWCZMRAu2TAJ9QluvFRh2Hvu2T1p6DxOkhsD+gUgCgvYjC qQ12BqJsAQHxMEfBkLTodAw= =LvhF -----END PGP SIGNATURE----- -- gentoo-user@gentoo.org mailing list