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?

3

4 Answers 4

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)).

2

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

7
  • This seems to assume that you have set the extglob shell option in bash, right? ls -d .[!.]* wouldbe easier.
    – Kusalananda
    May 28, 2020 at 11:26
  • Ahh yes, it appears so. Will update May 28, 2020 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, 2020 at 12:33
  • @ilkkachu what would be the extension to the globs version to include ..?* May 29, 2020 at 11:20
  • 1
    @jonnybolton16, that extended glob version should work already, .!(|.) matches ..foo etc.
    – ilkkachu
    May 29, 2020 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.

2
  • 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. May 28, 2020 at 11:07
  • @jonnybolton16 See my edit. May 28, 2020 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.

2
  • 1
    GLOBIGNORE=.:.. works fine in bash.
    – user232326
    May 28, 2020 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, 2020 at 13:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .