6

Normally dot files are not included for wildcard expansion:

% echo *
Applications Desktop Documents Downloads Library Movies Music Pictures Public bin

If I explicitly ask for dot files, I get them:

% echo * .*
Applications Desktop Documents Downloads Library Movies Music Pictures Public bin . .. .CFUserTextEncoding .DS_Store .Trash .adobe .bash_history .cups .gitconfig .gnupg .history .lesshst .netbeans .scanview.cfg .sqlite_history .ssh .swt .systemmodeler .tcshrc .viminfo

However I also get . and ... I don't want those, for example if I'm passing to du -s where I want the size of every item in the directory. Is there some pattern that gives me just what's in the current directory, and everything in the current directory without . and ..?

I use tcsh.

(With regard to the "This question may already have an answer here:" note above: no this question doesn't have an answer there, since that answer only works for bash.)

Mark Adler
  • 1,995

6 Answers6

6

With tcsh 6.17.01 and above:

set globdot
du -s -- *

With older ones:

du -s -- * .[^.]* ..?*

(interestingly, that works better than its POSIX counterpart (* .[!.]* ..?*) because in tcsh (and in zsh in csh emulation (cshnullglob option)), contrary to POSIX shells, those pattern that don't match any file get expanded to nothing instead of themselves)

With standard find:

find . ! -name . -prune -exec du -s {} +

Note that GNU du has a -d option to limit the depth at which dir disk usage are reported:

du -ad1
2

You can use ls -A command to not enlist . and .. inside command substitution:

echo "`ls -A`"
Nykakin
  • 3,979
  • du * will work even if there are names with spaces in the directory. du \ls -A`` will not (and du "\ls -A`"` will not work at all). – derobert May 14 '13 at 15:23
  • @derobert, why...? I've tried du "\ls -A`"` in test directory and it seemed to work well. – Nykakin May 14 '13 at 15:34
  • Did you have multiple items in that directory? I'd expect it to work with 1, but fail with 2 or more. I guess its possible tcsh does something weird there... – derobert May 14 '13 at 15:39
  • In my case it worked fine even for /etc dir. – Nykakin May 14 '13 at 15:43
  • Indeed, you're right, that does work in tcsh. At least unless your filenames contain newlines, which is sufficiently uncommon that its probably ignorable. – derobert May 14 '13 at 15:47
2

I usually use:

du -ks * .[^.]*

This way . and .. are not matched and it should be fairly portable.

michas
  • 21,510
1

Not sure if there is a tcsh builtin, but depending on the version of find you have, there is a workaround like this:

find -maxdepth 1 -not -name '.' -exec du -s '{}' '+'

If your find doesn't do the -exec COMMAND {} + syntax, you can try for -print0/xargs:

find -maxdepth 1 -not -name '.' -print0 | xargs -0 du -s
derobert
  • 109,670
1

There is no simple generic solution as it is shell dependent:

For tcsh or bash:

echo .[^.]*

For ksh:

echo .*

However, it will fail in Nykakin's case (files beginning with ..)

For a more generic answer, use "grep" or "find", like in:

ls -a|grep '^\.\(..\|[^\.]\)'

This works with all shells I know and doesn't have the Nykakin's case. Also works with those following special cases that other solutions could fail:

.x
.x.
..x.

It means: Start with a dot, followed by at least 2 characters or a character that isn't a dot.

Le Droid
  • 111
0

a way (but may choke or have side effects on strange filenames, ie files whose name contain a newline! but also files containing * or a " or ... you get the picture ^^. Be very careful if using those way to list and use files)

$ for i in * .* ; do echo $i ; done | egrep -v '^\.$|^\.\.$' > /tmp/list_files_one_by_lines
$ while read a_file ; do echo something on "${a_file}" ; done < /tmp/list_files_one_by_lines

so you should better use : find

more exactly:

find . -mindepth 1 -print0 | xargs -0 some_command

this is why:

$ find . | egrep '^\.$|^\.\.$'
.
$ find . -mindepth 1 | grep '^\.$'
$ 

and the use of -print0 | xargs -0 .... allow to take care of almost every special characters that could occur in a filename (newline, quotes, ;, ctrl+z, you name it)