On 4 April 2014 12:16, Chris Angelico <ros...@gmail.com> wrote: > On Fri, Apr 4, 2014 at 11:15 AM, David <bouncingc...@gmail.com> wrote: >> On 4 April 2014 01:17, Chris Angelico <ros...@gmail.com> wrote: >>> >>> -- Get info on all .pyc files in a directory and all its subdirectories -- >>> C:\>dir some_directory\*.pyc /s >>> $ ls -l `find some_directory -name \*.pyc` >>> >>> Except that the ls version there can't handle names with spaces in >>> them, so you need to faff around with null termination and stuff. >> >> Nooo, that stinks! There's no need to abuse 'find' like that, unless >> the version you have is truly ancient. Null termination is only >> necessary to pass 'find' results *via the shell*. Instead, ask 'find' >> to invoke the task itself. >> >> The simplest way is: >> >> find some_directory -name '*.pyc' -ls >> >> 'find' is the tool to use for *finding* things, not 'ls', which is >> intended for terminal display of directory information. > > I used ls only as a first example, and then picked up an extremely > common next example (deleting files). It so happens that find can > '-delete' its found files, but my point is that on DOS/Windows, every > command has to explicitly support subdirectories. If, instead, the > 'find' command has to explicitly support everything you might want to > do to files, that's even worse! So we need an execution form... > >> If you require a particular feature of 'ls', or any other command, you >> can ask 'find' to invoke it directly (not via a shell): >> >> find some_directory -name '*.pyc' -exec ls -l {} \; > > ... which this looks like, but it's not equivalent.
> That will execute > 'ls -l' once for each file. You can tell, because the columns aren't > aligned; for anything more complicated than simply 'ls -l', you > potentially destroy any chance at bulk operations. Thanks for elaborating that point. But still ... > equivalent it *must* pass all the args to a single invocation of the > program. You need to instead use xargs if you want it to be > equivalent, and it's now getting to be quite an incantation: > > find some_directory -name \*.pyc -print0|xargs -0 ls -l > > And *that* is equivalent to the original, but it's way *way* longer > and less convenient, which was my point. If you are not already aware, it might interest you that 'find' in (GNU findutils) 4.4.2. has -- Action: -execdir command {} + This works as for `-execdir command ;', except that the `{}' at the end of the command is expanded to a list of names of matching files. This expansion is done in such a way as to avoid exceeding the maximum command line length available on the system. Only one `{}' is allowed within the command, and it must appear at the end, immediately before the `+'. A `+' appearing in any position other than immediately after `{}' is not considered to be special (that is, it does not terminate the command). I believe that achieves the goal, without involving the shell. It also has an -exec equivalent that works the same but has an unrelated security issue and not recommended. But if that '+' instead of ';' feature is not available on the target system, then as far as I am aware it would be necessary to use xargs as you say. Anyway, the two points I wished to contribute are: 1) It is preferable to avoid shell command substitutions (the backticks in the first example) and expansions where possible. 2) My observations on 'find' syntax, for anyone interested. Cheers, David -- https://mail.python.org/mailman/listinfo/python-list