how to write a script to only process one depth directories

R

robertchen117

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.
 
J

Josef Moellers

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.

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
 
J

Jürgen Exner

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?

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?
 
M

Martijn Lievaart

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.

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
 
M

Martijn Lievaart

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
 
R

Randal L. Schwartz

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"
 
M

Martijn Lievaart

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
 
T

Tim McDaniel

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top