On 07/17/2017 04:23 PM, Kaz Kylheku (Coreutils) wrote:
> Well, if it has to be fast, perhaps don't write the code in the shell
> language.

Too true.  But that's starting to get off-topic for coreutils (and more
appropriate for the bash list).

> 
> Even an interpreted scripting language that can do string handling without
> resorting to fork()-based command substitution will beat the shell at many
> tasks.
> 
>>> it can be done like this:
>>>
>>>    for name in dir/*txt ; do
>>>      echo ${name#dir/}
>>>    done
>>
>> I would like to avoid such an operation “Remove matching prefix
>> pattern” generally.
>> If the desired file lists contain only basenames, extra prefixes do
>> not need
>> to be deleted.
> 
> I.e. we can use the basename function:
> 
>   for name in dir/*txt; do
>     basename "$name"
>   done

basename is not (generally) a shell builtin.  You are fork()ing out to
one basename process per filename with this code, UNLESS you've defined
basename as a shell function - but the definition of said shell function
would resemble the 'echo ${name#dir/}' line from above.  And writing a
POSIX-compliant basename shell function is not trivial (a number of
attempts on the web get it horribly wrong on the corner cases).

GNU coreutils' basename _does_ have an extension beyond POSIX that lets
you get by with fewer processes (one process for the entire list, rather
than one per member of the list):

basename -a dir/*txt

insofar as you don't run into command-line length limits (and you may
want to mix with -z to avoid ambiguities with newlines embedded in those
filenames).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to