in reply to Re: Re: Re: Re: Re: Need one-liner to s///g in all sub-dirs
in thread Need one-liner to s///g in all sub-dirs

I have done as you suggested (did you?). And my observation is that ls ./*/* reports first on files that are one level below the current directory, i.e. files in the immediate sub-directories (which is what I want). And in addition ls seems to automatically recurse if given a wildcard. So it also reports recursively on sub-directories of those one-level-down directories. My explanation:
. the current directory /* all dirs in next level down /* all files in those dirs
and recurse from there.

If the recursion happens with the perl example, it doesn't matter in my case since there is nothing there.

I'd still like to know if %perl -pie 's/old/new/g' ./*/* does what I want.

Meditation: This whole thing has taken a direction that I am bemused by. I thought I was asking a simple and straightforward question. The discussion has ranged far and wide. And I find myself in the position of 'arguing' with answers that seem not to answer the question I asked but rather go in different directions. If I am seeming ungrateful, ungracious, or argumentative, I apologize. I really am just trying to get clarity on my measily half-line solution.

If my solution does not do what I want, just say that and explain where I have gone astray. And if my solution fails, I would be very happy to see a pure-perl command-line solution if that is possible.

Thanks to all for your (presumed) patience.

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Re: Need one-liner to s///g in all sub-dirs
by blakem (Monsignor) on Aug 25, 2001 at 10:34 UTC
    Lets break the '.*/*' approach down a bit, to help you understand the difference between the two

    perl -pie 's/old/new/g' ./*/*
    The first thing that happens when you enter this command into your shell, is that the shell expands the wildcards. This is important.... perl doesn't ever see the './*/*' construct. The shell then executes the expanded command which now looks like:
    perl -pie 's/old/new/g' subdir/file1 subdir/file2 subdir2/file1 subdir +2/subsubdir/
    And perl does its magic inplace editing on this list of files. (note, see the update to my previous post) No recursion is done. You've simply said, execute this perl command on the following files. Those files being ones that the shell matched with its './*/*' pattern.

    In otherwords, you could use that command like so:

    perl -pi -e 's/old/new/g' file1 dir1/file2 /usr/local/file3 /tmp/*
    You've passed the perl command a set of files which it will work with. (thats what the empty <> operator does that you've seen in the perlrun docs)

    On the other hand, the find solution will walk the filesystem executing the perl command on each file that matches its criteria (here its just </code>-type f</code> which means a regular file) Depending on your filesystem layout, this can be much more powerful than the other solution.

    Said another way... the find solution is equivalent to the following series of commands:

    perl -pie 's/old/new/g' ./* perl -pie 's/old/new/g' ./*/* perl -pie 's/old/new/g' ./*/*/* perl -pie 's/old/new/g' ./*/*/*/* perl -pie 's/old/new/g' ./*/*/*/*/* etc.....
    Of course you'll get errors about executing the command on directories, and you'll soon hit your shells 'too many arguments' limit. Therefore find is a better general solution, but './*/*' might work fine in any one instance.

    -Blake