From gwadej at anomaly.org Mon Aug 13 05:21:14 2007 From: gwadej at anomaly.org (G. Wade Johnson) Date: Mon, 13 Aug 2007 07:21:14 -0500 Subject: [pm-h] August Meeting Message-ID: <20070813072114.608da035@sovvan> Hi everyone, I've been unavailable for a week (no internet, no email, no cell phone, not even my pilot). I just wanted to remind everyone that this month's meeting is on Tuesday 8/14 (that's tomorrow). It's a social meeting, so we'll be meeting at the Bennigan's at 59 and Kirby as usual. For those of you who ordered YAPC t-shirts, I will have them with me and I'll take cash or check. If you would still like to order a t-shirt for me to bring to the meeting. You need to let me know today (or before 7am tomorrow). The shirts are $5 a piece and I have sizes from M to XXXL. See you there. G. Wade -- To vacillate or not to vacillate, that is the question ... or is it? From rlharris at oplink.net Sun Aug 19 23:50:18 2007 From: rlharris at oplink.net (Russell L. Harris) Date: Mon, 20 Aug 2007 01:50:18 -0500 Subject: [pm-h] substitution with increment Message-ID: <20070820065018.GA13282@oplink.net> I have several dozen groups of files; each group consists of one to several hundred files. Within each group, the bash "ls" command lists the files in proper order, because the filename includes a multi-character identifier (such as 43-29, 43-30, 44-01, 44-02, etc.). I need to add to the file names within each group a file number, such that the files may be referenced in proper order as 001, 002, 003, etc. It is important that the file number contain exactly three digits. I am making other changes to the filename, and I have been able to accomplish everything (undoubtedly crudely) with the diamond operator and the substitution operator s/// (using the "g" suffix). But I have not figured out a reasonable scheme for adding the sequential file number. Can this be done with s/// ? RLH From gwadej at anomaly.org Mon Aug 20 04:59:39 2007 From: gwadej at anomaly.org (G. Wade Johnson) Date: Mon, 20 Aug 2007 06:59:39 -0500 Subject: [pm-h] substitution with increment In-Reply-To: <20070820065018.GA13282@oplink.net> References: <20070820065018.GA13282@oplink.net> Message-ID: <20070820065939.5cb25923@sovvan> On Mon, 20 Aug 2007 01:50:18 -0500 "Russell L. Harris" wrote: > I have several dozen groups of files; each group consists of one to > several hundred files. > > Within each group, the bash "ls" command lists the files in proper > order, because the filename includes a multi-character identifier > (such as 43-29, 43-30, 44-01, 44-02, etc.). > > I need to add to the file names within each group a file number, such > that the files may be referenced in proper order as 001, 002, 003, > etc. It is important that the file number contain exactly three > digits. Constructing the file names looks like a job for sprintf. > I am making other changes to the filename, and I have been able to > accomplish everything (undoubtedly crudely) with the diamond operator > and the substitution operator s/// (using the "g" suffix). But I have > not figured out a reasonable scheme for adding the sequential file > number. Can this be done with s/// ? There's a great piece of code in the Perl Cookbook that works as a very powerful rename command. It takes the old filename, applies some Perl code to it, and then renames the file (if the old and new names are different). I would actually do this part separately from any other processing. Loop over the list of filenames, creating the new name from a counter. Use the rename() function to do the actual file renaming. One case where I have used it is renaming files from a digital camera. My camera generates files of the form DSCN0123.JPG. Let's say I wanted to rename a large set of them to have a more useful name, I would use the loop below. my $counter = 1; foreach $file (@ARGV) { my $newname = sprintf( 'Vacation2007-%04d.jpg', $counter ); if(!rename( $file, $newname )) { warn "Failed to rename $file to $newname\n"; } } You can also extract information from the old file name to use when constructing the new name. For example, say I just wanted to keep the old filenames, but change them from 4 digits at the end to five. foreach $file (@ARGV) { my $newname = $file; $newname =~ s/DSCN(\d+).JPG/DSCN0$1.JPG/; if(!rename( $file, $newname )) { warn "Failed to rename $file to $newname\n"; } } Hope that helps. G. Wade -- You forgot the first rule of the fanatic: when you become obsessed with the enemy, you become the enemy. -- Jeffrey Sinclair in "Infection" From rlharris at oplink.net Tue Aug 21 20:24:08 2007 From: rlharris at oplink.net (Russell L. Harris) Date: Tue, 21 Aug 2007 22:24:08 -0500 Subject: [pm-h] substitution with increment In-Reply-To: <20070820065939.5cb25923@sovvan> References: <20070820065018.GA13282@oplink.net> <20070820065939.5cb25923@sovvan> Message-ID: <20070822032408.GA6997@oplink.net> * G. Wade Johnson [070820 19:59]: > Constructing the file names looks like a job for sprintf. Thanks. I noticed print and sprint when I read "Learning Perl", but until now I had no concept of the versatility of the utility. > There's a great piece of code in the Perl Cookbook ... I should have known I would reget ordering the seventh volume of Harry Potter rather than the cookbook. OK; the cookbook is back at the top of my "books to purchase" list. > ... the loop below. > > my $counter = 1; > foreach $file (@ARGV) > { > my $newname = sprintf( 'Vacation2007-%04d.jpg', $counter ); > if(!rename( $file, $newname )) > { > warn "Failed to rename $file to $newname\n"; > } > } The most prominent gap in my understanding of Perl is how to apply Perl code such as this to a file or to sets of files. This includes my comprehension of the diamond operator, which is minimal. But I suppose that the Perl Cookbook is the best way to learn the techniques. > Hope that helps. Yes; thanks. RLH From gwadej at anomaly.org Wed Aug 22 05:07:04 2007 From: gwadej at anomaly.org (G. Wade Johnson) Date: Wed, 22 Aug 2007 07:07:04 -0500 Subject: [pm-h] substitution with increment In-Reply-To: <20070822032408.GA6997@oplink.net> References: <20070820065018.GA13282@oplink.net> <20070820065939.5cb25923@sovvan> <20070822032408.GA6997@oplink.net> Message-ID: <20070822070704.787a2920@sovvan> On Tue, 21 Aug 2007 22:24:08 -0500 "Russell L. Harris" wrote: > * G. Wade Johnson [070820 19:59]: > > Constructing the file names looks like a job for sprintf. > > Thanks. I noticed print and sprint when I read "Learning Perl", but > until now I had no concept of the versatility of the utility. For those who have programmed in C or C++, printf/sprintf are equivalent to the same functions in C. > > There's a great piece of code in the Perl Cookbook ... > > I should have known I would reget ordering the seventh volume of Harry > Potter rather than the cookbook. OK; the cookbook is back at the top > of my "books to purchase" list. > > > > > ... the loop below. > > > > my $counter = 1; > > foreach $file (@ARGV) > > { > > my $newname = sprintf( 'Vacation2007-%04d.jpg', $counter ); > > if(!rename( $file, $newname )) > > { > > warn "Failed to rename $file to $newname\n"; > > } > > } > > The most prominent gap in my understanding of Perl is how to apply > Perl code such as this to a file or to sets of files. This includes > my comprehension of the diamond operator, which is minimal. But I > suppose that the Perl Cookbook is the best way to learn the > techniques. The key piece of information for this code is that @ARGV contains the command line parameters passed to the script. So this little piece of code expect you to pass a series of filenames as the command line to the script. More importantly, the script renames the files based on the order of the command line parameters. So, if we had the code above in the script rename_pics.pl, and called it with the following: rename_pics.pl a.jpg b.jpg c.jpg The files would be renamed as shown below a.jpg -> Vacation2007-0001.jpg b.jpg -> Vacation2007-0002.jpg c.jpg -> Vacation2007-0003.jpg If, on the other hand, we called it with the following: rename_pics.pl b.jpg c.jpg a.jpg The files would be renamed as shown below b.jpg -> Vacation2007-0001.jpg c.jpg -> Vacation2007-0002.jpg a.jpg -> Vacation2007-0003.jpg Is that clearer? G. Wade -- The user's going to pick dancing pigs over security every time. -- Bruce Schneier From rlharris at oplink.net Wed Aug 29 15:12:55 2007 From: rlharris at oplink.net (Russell L. Harris) Date: Wed, 29 Aug 2007 17:12:55 -0500 Subject: [pm-h] use of $$ versus $ in makefile and bash Message-ID: <20070829221255.GA11603@oplink.net> I am puzzled concerning the use of the symbols "$" and "$$" in a makefile. I do not understand why "$$" is required in some instances, and "$" in other instances. I have spent several hours searching through the documentation for BASH and for GNU Make, and I have searched with Google, but I have found no answer. Here are three examples, all taken from the same makefile: EXAMPLE 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -(for d in ${SYMLINKDIR}; \ do \ pushd $$d && \ ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \ popd; \ done;) EXAMPLE 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (for d in $$(find . \ \( -type d \ -name '.svn' -prune -o \ -name 'miscellany' -prune -o \ -type d -print); \ do mkdir --parents ../stageweb/$$d; \ done;) EXAMPLE 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (for bn in ${CLEANDIR}; \ do \ rm -f $(addprefix $$bn/*.,${CLEANEXT}); \ done;) # Why was "bn" chosen as the name of the loop variable? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% My interest is fueled by the need to create a makefile which automates the following commands for any number of files, which necessitates a pair of for-loops: hevea -fix -I jan article.hva jan/jan-01.tex hevea -fix -I jan article.hva jan/jan-02.tex ... hevea -fix -I feb article.hva feb/feb-01.tex hevea -fix -I feb article.hva feb/feb-02.tex ... hevea -fix -I mar article.hva mar/mar-02.tex hevea -fix -I mar article.hva mar/mar-02.tex ... # (The hevea command creates files named "jan-01.html", etc.) cp jan/jan-*.html ../stageweb/jan/ cp jan/feb-*.html ../stageweb/feb/ cp jan/mar-*.html ../stageweb/mar/ ... Looking at other code in the makefile which I am using for a go-by, I expect to start out with variables such as: JAN := $(wildcard jan/jan*.tex) FEB := $(wildcard feb/feb*.tex) MAR := $(wildcard mar/mar*.tex) ... DOCUMENTS := $(JAN) $(FEB) $(MAR) ... or else: MONTHS := jan feb mar ... RLH From gwadej at anomaly.org Thu Aug 30 05:22:12 2007 From: gwadej at anomaly.org (G. Wade Johnson) Date: Thu, 30 Aug 2007 07:22:12 -0500 Subject: [pm-h] use of $$ versus $ in makefile and bash In-Reply-To: <20070829221255.GA11603@oplink.net> References: <20070829221255.GA11603@oplink.net> Message-ID: <20070830072212.7cb6fbed@sovvan> On Wed, 29 Aug 2007 17:12:55 -0500 "Russell L. Harris" wrote: > I am puzzled concerning the use of the symbols "$" and "$$" in a > makefile. I do not understand why "$$" is required in some instances, > and "$" in other instances. According to "Managing Project with make" by Oram and Talbott, $$ in make is causes a $ to be used in the command instead of being evaluated as part of a make variable. > I have spent several hours searching through the documentation for > BASH and for GNU Make, and I have searched with Google, but I have > found no answer. > > Here are three examples, all taken from the same makefile: > > EXAMPLE 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > > -(for d in ${SYMLINKDIR}; \ > do \ > pushd $$d && \ > ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \ > popd; \ > done;) If you were working in a regular shell script, this would be something like: (for d in some_dir_name; \ do \ pushd $d && \ ln -sf some_target_name .; \ popd; \ done;) In order for make not to treat '$d' as a make variable, you need to double the $. > > EXAMPLE 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > > (for d in $$(find . \ > \( -type d \ > -name '.svn' -prune -o \ > -name 'miscellany' -prune -o \ > -type d -print); \ > do mkdir --parents ../stageweb/$$d; \ > done;) > > EXAMPLE 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > > (for bn in ${CLEANDIR}; \ > do \ > rm -f $(addprefix $$bn/*.,${CLEANEXT}); \ > done;) > > # Why was "bn" chosen as the name of the loop variable? > > %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > > My interest is fueled by the need to create a makefile which automates > the following commands for any number of files, which necessitates a > pair of for-loops: > > hevea -fix -I jan article.hva jan/jan-01.tex > hevea -fix -I jan article.hva jan/jan-02.tex > ... > hevea -fix -I feb article.hva feb/feb-01.tex > hevea -fix -I feb article.hva feb/feb-02.tex > ... > hevea -fix -I mar article.hva mar/mar-02.tex > hevea -fix -I mar article.hva mar/mar-02.tex > ... > > # (The hevea command creates files named "jan-01.html", etc.) > > cp jan/jan-*.html ../stageweb/jan/ > cp jan/feb-*.html ../stageweb/feb/ > cp jan/mar-*.html ../stageweb/mar/ > ... > > Looking at other code in the makefile which I am using for a go-by, I > expect to start out with variables such as: > > JAN := $(wildcard jan/jan*.tex) > FEB := $(wildcard feb/feb*.tex) > MAR := $(wildcard mar/mar*.tex) > ... > > DOCUMENTS := $(JAN) $(FEB) $(MAR) ... > > or else: > > MONTHS := jan feb mar ... > > RLH G. Wade -- It's easier to port a shell than a shell script. -- Larry Wall From rlharris at oplink.net Thu Aug 30 13:33:57 2007 From: rlharris at oplink.net (Russell L. Harris) Date: Thu, 30 Aug 2007 15:33:57 -0500 Subject: [pm-h] use of $$ versus $ in makefile and bash In-Reply-To: <20070830072212.7cb6fbed@sovvan> References: <20070829221255.GA11603@oplink.net> <20070830072212.7cb6fbed@sovvan> Message-ID: <20070830203357.GA9706@oplink.net> * G. Wade Johnson [070830 07:28]: > On Wed, 29 Aug 2007 17:12:55 -0500 > "Russell L. Harris" wrote: > >> I am puzzled concerning the use of the symbols "$" and "$$" in a >> makefile. I do not understand why "$$" is required in some instances, >> and "$" in other instances. > > According to "Managing Project with make" by Oram and Talbott, $$ in > make causes a $ to be used in the command instead of being evaluated > as part of a make variable. Thanks for an explanation which makes sense; the GNU Make manual is ambiguous, to say the least: "To substitute a variable's value, write a dollar sign followed by the name of the variable in parentheses or braces: either `$(foo)' or `${foo}' is a valid reference to the variable foo. This special significance of `$' is why you must write `$$' to have the effect of a single dollar sign in a file name or command." (from section 6.1) The authors of such manuals seem never to test the manual by giving it to someone unfamiliar with the subject and asking him to flag passages which are not clear. >> EXAMPLE 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >> >> -(for d in ${SYMLINKDIR}; \ >> do \ >> pushd $$d && \ >> ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \ >> popd; \ >> done;) In the case of a variable name for which there is no possibility of expansion (or there is such a thing?), would not the following be equivalent? -(for d in ${SYMLINKDIR}; \ do \ pushd $(d) && \ ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \ popd; \ done;) RLH From gwadej at anomaly.org Thu Aug 30 16:50:11 2007 From: gwadej at anomaly.org (G. Wade Johnson) Date: Thu, 30 Aug 2007 18:50:11 -0500 Subject: [pm-h] use of $$ versus $ in makefile and bash In-Reply-To: <20070830203357.GA9706@oplink.net> References: <20070829221255.GA11603@oplink.net> <20070830072212.7cb6fbed@sovvan> <20070830203357.GA9706@oplink.net> Message-ID: <20070830185011.1f6d67f3@sovvan> On Thu, 30 Aug 2007 15:33:57 -0500 "Russell L. Harris" wrote: > * G. Wade Johnson [070830 07:28]: > > On Wed, 29 Aug 2007 17:12:55 -0500 > > "Russell L. Harris" wrote: > > > >> I am puzzled concerning the use of the symbols "$" and "$$" in a > >> makefile. I do not understand why "$$" is required in some > >> instances, and "$" in other instances. > > > > According to "Managing Project with make" by Oram and Talbott, $$ in > > make causes a $ to be used in the command instead of being evaluated > > as part of a make variable. > > Thanks for an explanation which makes sense; the GNU Make manual is > ambiguous, to say the least: > > "To substitute a variable's value, write a dollar sign followed by > the name of the variable in parentheses or braces: either `$(foo)' > or `${foo}' is a valid reference to the variable foo. This special > significance of `$' is why you must write `$$' to have the effect > of a single dollar sign in a file name or command." (from section > 6.1) > > The authors of such manuals seem never to test the manual by giving it > to someone unfamiliar with the subject and asking him to flag passages > which are not clear. It is hard finding people to proofread all of the documentation. > >> EXAMPLE 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > >> > >> -(for d in ${SYMLINKDIR}; \ > >> do \ > >> pushd $$d && \ > >> ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \ > >> popd; \ > >> done;) > > In the case of a variable name for which there is no possibility of > expansion (or there is such a thing?), would not the following be > equivalent? > > -(for d in ${SYMLINKDIR}; \ > do \ > pushd $(d) && \ > ln -sf $(addprefix ../,${SYMLINKTARGET}) .; \ > popd; \ > done;) It's perfectly legal to have a variable whose value is an empty string. To make matters worse, you can define make variables on the command line. So, how would make know whether or not $d might refer to a variable that just isn't defined on this run. And, if you treated it differently depending on whether or not it was defined, there would be even nastier bugs to find. Using '$$' as an escape for '$' appears to be the lesser evil. G. Wade -- Results are what you wanted, consequences are what you got. -- Michael VanDusen