help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Glob star pattern does not match files beginning with a


From: Eric Blake
Subject: Re: [Help-bash] Glob star pattern does not match files beginning with a period
Date: Thu, 16 Jul 2015 06:52:43 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.0.1

On 07/15/2015 06:49 PM, Michael Convey wrote:

> ​I see that now. I do have files listed twice.​ Looks like the following
> really is the best way to go:
> shopt -s dotglob
> ls -dl *
> I was trying to see if I could do it without changing that option. What are
> the downsides to leaving the dotglob on by default?

It lists hidden files by default, which may break expectations of some
scripts.  But for interactive use, its a judgment call for what you feel
comfortable with.

> 
>>
>> Both of these three-glob approaches can be used to obtain all file names
>> that are not '.' or '..':
>>
>> ​​
>> ls -d * .[!.]* ..?*
>>
>> or:
>>
>> ls -d * .??* .[!.]
>>
> 
> ​I assume you intended and asterisk at the end of the preceding line. ​

No, because that would then list some files twice.  The second pattern
lists all non-hidden files, all files starting with '.' and at least 3
bytes, and all files starting with '.' and exactly two bytes while
excluding '..'.  But using .[!.]* would list '.aa' twice.


> ​Interesting. When I execute each of the following commands in an empty
> directory, i get an error:
> 
> ls -d .??*
> ls -d ..?*
>
> ls -d .[!.]*

Because the glob failed to match so it was passed verbatim to ls, which
then discovers ENOENT trying to resolve the name.

> 
> ​However, if I set nullglob, each of those commands outputs '.' -- which
> doesn't seem right. ​

But it IS right.  The patterns expand to nothing, and you are now
invoking 'ls -d', and ls operates on '.' when there are no arguments.
In this scenario, you have to combine the glob that might be eliminated
by nullglob with some other argument so that ls isn't operating on zero
arguments.  But then you have a race on determining whether the
directory was empty before trying to use ls.

If all you are trying to do is list file names, then 'echo PATTERN' is
almost always going to be better than 'ls -d PATTERN'.

> 
> 
>> There is no two-glob pattern that can cover all file names except for .
>> and .., unless you resort to bash's extended globs (at which point, you
>> might as well do it in a single glob that uses alternation).
>>
>> ​By alternation, do you mean something like the following:
> 
> ls -dl * -o .[!.]*​ -o ..?*

No, I mean something like:

shopt -s extglob
ls -dl !(.|..)

> 
> This seems to work perfectly with no duplicate output and dotglob and
> nullglob unset.
> 
> However, the following produced an error:
> 
> ls -dl {*|.[!.]*​|..?*}

That's not valid extglob alternation

> 
> I also tried [...], but that errored as well. Is there another fairly
> simple way to perform alternation without using extended globs?

No; I was referring to alternation in the context of bash's extglob
extension, which is not portable to POSIX sh.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]