Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 01 Feb 2002 17:24:46 -0330
From:      Paul David Fardy <pdf@morgan.ucs.mun.ca>
To:        "Crist J. Clark" <cristjc@earthlink.net>
Cc:        <questions@FreeBSD.ORG>, Eric Six <erics@sirsi.com>
Subject:   Re: Perl question...
Message-ID:  <200202012054.g11KslkB001080@plato.ucs.mun.ca>

next in thread | raw e-mail | index | archive | help
Eric Six <erics@sirsi.com> wrote:
>> I have found ways to append lines to the file, but not to create a new
>> one at the very beginning. Also, any ideas on how to automate doing
>> this to all the files in each dir?

"Crist J. Clark" <cristjc@earthlink.net> wrote:
> ed(1) man. man ed.
>
>	for FILE in $DIR; do
>		ed $DIR/$FILE <<"EOF"
>	1i
>	$TTL value
>	.
>	wq
>	EOF
>	done

I've been using Perl so much, I've forgotten some of my shell rules.
I tested this code because I thought "$TTL" would result in the
expansion of an undefined variable TTL.  In Perl, it _would_ be a
problem.  In sh, it's fine.

But I think I'll still add a few notes.

>	for FILE in $DIR; do
>		ed $DIR/$FILE <<"EOF"

This should, I think, be

	for file in *; do
		ed $file <<"EOF"

or

	for file in */*; do
		ed $file <<"EOF"


Caveat: This is the syntax for the Bourne shell and its descendents/clones.
   It won't work in C Shell or its descendents/clones.  Put the code in a
   file and run it with /bin/sh.

Caveat: Some implementations of /bin/ed do not recognize "wq".  It's
   more portable to use:

	...
	1i
	$TTL value
	.
	w
	q

i.e. separating the wq into 2 commands.  (Bourne shell Tru64 UNIX doesn't
understand "wq".)

TMTOWTDI - There's more than one way to do it:

	for file in *; do
		perl -lp -i.bak -e 'print q($TTL 86400) if $. == 1' $file
	done

This has one advantage: the original files are saved as filename.bak.
And it has one disadvantage: while the man page suggests "-i" means
"in-place", it's not really.  The original file remains with a new
name; a new file is created and the protection and ownership of that
file are determined by the identity and the umask of the user running
this code.

Perl opts:  
    -e EXPR  -- supplies Perl expression
    -l       -- add newline to every print (no need of \n)
    -p       -- wraps EXPR: "while (<>) { EXPR } continue { print }"
    -i.bak   -- non-quite in-place (keep old files as "filename.bak")

Assuming you've put your zone files (and only you zone files) in a
subdirectory, you can run

    find /var/named/master -type f | \
        xargs perl -lp -i.bak \
           -e 'print q($TTL 86400) if $. == 1; close ARGV if eof'

The last bit of code has the effect of resetting "$." at the end of
each file.

Paul Fardy
-- 
BSD's date has 'date -r', but many UNIX systems don't.  One of my
favourite "perl -le" expressions converts UNIX seconds to date:
The log file say time=1012596293. When was that?

	perl -le 'print scalar localtime 1012596293'

Your password expires in 90 days.  When is that?

	perl -le 'print scalar localtime(time + 90*86400)'

(or 90*24*60*60) :-)

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202012054.g11KslkB001080>