1

ls -d .* lists only hidden "items" (files & directories). (I think) technically it lists every item beginning with ., which includes the current . and above .. directories.

I also know that ls -A lists "almost all" of the items, listing both hidden and un-hidden items, but excluding . and ... However, combining these as ls -dA .* doesn't list "almost all" of my hidden items.

How can I exclude . and .. when listing only hidden items?

2

You can just combine all cases excluding . and .. 1. This won't choke on special filenames either:

ls -d .[!.]* ..?*

If the directory has really too much content, risking the command to fail with Argument list too long, then this can be used instead (but the optional -printf '%f\n' to remove the leading ./ is specific to GNU find and -maxdepth doesn't exist in POSIX):

find . -maxdepth 1 -name '.*' ! '(' -name . -o -name .. ')' -printf '%f\n'  

To then handle special characters such as LF, an option like -print0 can be used, but then all tools must support it (GNU or FreeBSD variants do except -printf '%f\0' which appears GNU-only and which can be replaced with -print0 but leaving the leading ./):

find . -maxdepth 1 -name '.*' ! '(' -name . -o -name .. ')'   -printf '%f\0'| sort -z | xargs -0 [...]

1: POSIX specifies the bracket starts as [! for negating a character in filename expansion, not [^ (as in regex) which has unspecified results (even if for example bash allows it)).

1

This has been answered over at Ask Ubuntu, which I will reproduce here:

ls -d .!(|.) with Bash's extended globs (shopt -s extglob to enable)

ls -d .[!.]* ..?* if not

  • This seems to assume that you have set the extglob shell option in bash, right? ls -d .[!.]* wouldbe easier. – Kusalananda May 28 '20 at 11:26
  • Ahh yes, it appears so. Will update – jonnybolton16 May 28 '20 at 11:58
  • Note that .[!.]* misses things like ..foo or ...bar. They should be rare, but for completeness, you'd need to add ..?* (or .??*) as mentioned in A.B.:s answer. – ilkkachu May 28 '20 at 12:33
  • @ilkkachu what would be the extension to the globs version to include ..?* – jonnybolton16 May 29 '20 at 11:20
  • 1
    @jonnybolton16, that extended glob version should work already, .!(|.) matches ..foo etc. – ilkkachu May 29 '20 at 13:56
1

If you just want to list the hidden files without . and ..

ls -ld .[!.]*

If you just wanted to list all files whether hidden or not without . or .. then you could just use:

ls -lA

That includes l for long listing and A to show the hidden and unhidden items without . and ..

-d just lists a directory and not its contents. As you just want to list the contents of the folder that you are in, you don't need it.

If you don't want a long listing, remove the -l.

  • This doesn't answer the question. I want to exclude . & .. when listing only hidden items. I already have ls -A for listing both hidden and non-hidden items. – jonnybolton16 May 28 '20 at 11:07
  • @jonnybolton16 See my edit. – Nasir Riley May 28 '20 at 13:09
-2

The problem you are observing is a result that is caused by a hack from the early days of UNIX in the early 1970s. In order to reduce the code size, a directory has been given real . and .. entries that ave been implemented as directory hard links to the current directory and the directory one level above. Modern filesystems have a different internal structure...

A nice way to deal with this problem is to select a shell that does not include . and .. in the list of matching files for the expression .*.

bosh and mksh are such shells. If you like to test a shell, I recommend to call:

mkdir /tmp/t
cd /tmp/t
echo .*

If the result is:

. ..

Your shell includes those paterns in the matching results, if you get:

.*

your shell excludes . and .. from the results. But be careful, since this result may also be caused by a filesystem does may not have . and .. entries, so also check whether:

ls -Fa

lists these files.

POSIX has been changed a while ago and now permits this behavior. Future POSIX versions may disallow to include . and .. in the matching results, since a filesystem is not even required to physically support these directories. The only requirement from POSIX is to implement the expected behavior when such a path is accessed.

  • 1
    GLOBIGNORE=.:.. works fine in bash. – Isaac May 28 '20 at 13:39
  • Thank you for the hint, but this is something I would expect as a set -o method. bosh permits to disable the feature via set +o globskipdot. BTW: The downvoting trolls are out again.... – schily May 28 '20 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.