Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to write a script to only process one depth directories

0 views
Skip to first unread message

robert...@gmail.com

unread,
Jul 2, 2009, 4:14:47 AM7/2/09
to
my directory /server has many servers under it, each /server/server1/
is a directory. I only want to find files like and add/change some
contents:

/server/server1/Defaults
/server/server2/Defaults
......
/server/servern/Defaults

and process it, for any other sub directories just ignore them. How to
do this in perl?
Please help me, thanks.

Josef Moellers

unread,
Jul 2, 2009, 4:35:06 AM7/2/09
to

The obvious question is: What have you tried so far and where did your
code not meet your expectations?

Hint:

foreach (</server/server*/Defaults>) {
# ...
}

Josef
--
These are my personal views and not those of Fujitsu Technology Solutions!
Josef M�llers (Pinguinpfleger bei FTS)
If failure had no penalty success would not be a prize (T. Pratchett)
Company Details: http://de.ts.fujitsu.com/imprint.html

J�rgen Exner

unread,
Jul 2, 2009, 8:19:07 AM7/2/09
to

One way:

glob() do get the file list, for() to loop through it, open() to access
the file, <> to get the content, print() to write the processed content
back, close() to, well, close the file again.

Which area do you have problems withj?

Martijn Lievaart

unread,
Jul 5, 2009, 8:02:14 AM7/5/09
to

Not a completely Perl based solution, but I would do:

echo /server/server*/Defaults | xargs perl -pi <script>

(or use some other flags to perl, depending on your requirements)

(btw, using (build in!) echo avoids command line length limits, don't use
ls. Gnu find is another good solution, but echo is wayyy simpler in this
case.)

(note: does NOT work if you have spaces or other whitespace characters in
file names!)

M4

Tim Landscheidt

unread,
Jul 5, 2009, 9:01:31 AM7/5/09
to
Martijn Lievaart <m...@rtij.nl.invlalid> wrote:

>> /server/server1/Defaults
>> /server/server2/Defaults
>> ......
>> /server/servern/Defaults

So: Use "find -print0" and "xargs -0r". Or, in this particu-
lar case, "perl -pi $SCRIPT /server/server*/Defaults". Oh,
and always use "-i.bak" while you're at it.

Tim

Martijn Lievaart

unread,
Jul 5, 2009, 11:00:05 PM7/5/09
to
On Sun, 05 Jul 2009 13:01:31 +0000, Tim Landscheidt wrote:

>> (btw, using (build in!) echo avoids command line length limits, don't
>> use ls. Gnu find is another good solution, but echo is wayyy simpler in
>> this case.)
>
>> (note: does NOT work if you have spaces or other whitespace characters
>> in file names!)
>
> So: Use "find -print0" and "xargs -0r". Or, in this particu- lar case,
> "perl -pi $SCRIPT /server/server*/Defaults". Oh, and always use "-i.bak"
> while you're at it.

This does not do what the OP wants without additional flags, and is Gnu
specific as well. It can work with something like (untested):

find /server -path '/server/server*/' -midepth 2 -maxdepth 2 -name
Default -print0 | xargs -0r ......

Otherwise you may run into command line limits again. A non Gnu solution
would be something like (again untested):

echo /server/server*/Defaults | while read f; do perl -pi $SCRIPT; done

This still does not account for file names with embedded newlines, but
those are rare enough not to worry about them in most cases.

M4

M4

Randal L. Schwartz

unread,
Jul 5, 2009, 11:10:46 PM7/5/09
to
>>>>> "Martijn" == Martijn Lievaart <m...@rtij.nl.invlalid> writes:

Martijn> echo /server/server*/Defaults | while read f; do perl -pi $SCRIPT; done

I don't think that'll do it.

echo will generate something like:

/server/server1/Defaults /server/server2/Defaults /server/server3/Defaults

which "read f" will read all at once making $f to be

"/server/server1/Defaults /server/server2/Defaults /server/server3/Defaults"

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<mer...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

Martijn Lievaart

unread,
Jul 6, 2009, 2:39:55 AM7/6/09
to
On Sun, 05 Jul 2009 20:10:46 -0700, Randal L. Schwartz wrote:

>>>>>> "Martijn" == Martijn Lievaart <m...@rtij.nl.invlalid> writes:
>
> Martijn> echo /server/server*/Defaults | while read f; do perl -pi
> $SCRIPT; done
>
> I don't think that'll do it.
>
> echo will generate something like:
>
> /server/server1/Defaults /server/server2/Defaults
> /server/server3/Defaults
>
> which "read f" will read all at once making $f to be
>
> "/server/server1/Defaults /server/server2/Defaults
> /server/server3/Defaults"

You're right. I'll think about it some more. Shows again this simple
problem is not simple solvable in shell without gnu utilities. So there
is a lot to be said for the Perl solution after all.

OK, how about this:

ls /server | grep ^server | while read f; do if [ -e "/server/$f/
Default" ]; then perl -pi $SCRIPT "$f" ; fi; done

Oh, this is a Perl newsgroup, I'll let it go at this.

M4

Tim McDaniel

unread,
Jul 6, 2009, 2:39:49 PM7/6/09
to
In article <86prcea...@blue.stonehenge.com>,

Randal L. Schwartz <mer...@stonehenge.com> wrote:
>>>>>> "Martijn" == Martijn Lievaart <m...@rtij.nl.invlalid> writes:
>
>Martijn> echo /server/server*/Defaults | while read f; do perl -pi $SCRIPT; done
>
>I don't think that'll do it.
>
>echo will generate something like:
>
> /server/server1/Defaults /server/server2/Defaults /server/server3/Defaults
>
>which "read f" will read all at once making $f to be
>
> "/server/server1/Defaults /server/server2/Defaults /server/server3/Defaults"

echo /server/server*/Defaults | xargs -n 1 |


while read f; do perl -pi "$SCRIPT"; done

The xargs(1) man page says

... xargs reads items from the standard input ... and executes the
command (default is /bin/echo) one or more times ...

-n max-args

Use at most max-args arguments per command line. ...


But I, too, still don't like that it doesn't handle shell
metacharacters in the filenames.

--
Tim McDaniel, tm...@panix.com

0 new messages