2009-01-21, 02:48(+01), Sebastian Kapfer:
> Am Montag, den 19.01.2009, 10:14 -0800 schrieb Alex Reed:
>> Should the globstar (**) syntax allow for partial parameter matching
>> (i.e. **.c to find all *.c files in the current directory and its sub-
>> directories)?
>> Currently this can be implemented like this:
>> for i in **; do if [[ ${i} =~ \.c$ ]]; then <my_operation>; fi; done
> Huh?
> So what's the difference between the following two lines
>       echo **
>       echo `find`

echo **

passes one argument per file name in the current directory to
echo. It ommit dot files, doesn't descend into dot dirs, and
sorts the file list.

echo `find`

(or standardly:
echo `find .`)

Takes the output of find, split it on spaces tabs and newlines,
then performs filename generation on each word resulting from
that splitting. All in all, there's no guarantee that the
arguments passed to echo are actual file paths. It includes the
dot files, and doesn't sort the list.

That feature comes from zsh. ksh93 was the first to copy it (but
is only enabled upon "set -G"). In zsh, ** is a shortcut for
(*/)# (0 or more directories). It's different in ksh, in that
for instance **.c matches all the c files while you need **/*.c
in zsh. zsh has ***/*.c to follow symlinks to directories when
descending. ** and *** are useful in combination with globbing
qualifiers in zsh, which allows one to effectively replace find.
For instance **/*.c(-.m-1om) expands to the list of .c files
(only regular files or symlinks to regular files, modified today
ordered by modification time. Doing the equivalent with find
would be cumbersome and almost impossible reliably.

A problem with **/*.. is that it makes it likely to reach the
execve(2) E2BIG limit on the number of arguments on some systems
(most except GNU Hurd and recent versions of Linux). ksh93 has a
work around for that.

Apparently, just like ksh93, bash4 only implements ** and not ***
nor the globbing qualifiers, but like zsh it requires **/*.c
(**.c won't work).


Reply via email to