0

I have the following alias defined in my .bashrc

    alias lsfc='ls -l "$@" | tee /dev/tty | grep -v / | echo "File count: `wc -l`"'

which is intended to give me the number of files in a directory but is giving me that number +1 - because it's also including the initial line giving the total size of the directory. How can I modify my alias to either exclude that first line or reduce the line count by one? I can't even begin to work out what to Google for to try and solve this on my own.

3
  • don't use -l if you don't want the information it prints. Or remove the first line with e.g. sed 1d. Or use the shell's arithmetic expansion to subtract one, $(( $(wc -l) - 1 )). But also note that if someone gives you a filename with a newline in it (something unix-like OSes sadly don't stop you from doing), some versions of ls will happily print it with a raw newline, messing up the count. Anyway, you should probably turn that into a shell function too, in particular because "$@" doesn't even work in an alias the way you'd hope it does.
    – ilkkachu
    Commented Sep 17 at 12:38
  • 3
  • Many thanks to all for the help and advice!
    – David Shaw
    Commented Sep 25 at 12:53

2 Answers 2

1

Aliases don't use or even understand parameters such as "$@", so immediately you will need to use a function or script. Here's one implementation:

lsfc() {
    local x=$(ls -lq -- "$@" );
    local n=$(wc -l <<<"$x");
    printf "%s\nFile count: %d\n" "$x" "$((n-1))"
}

Be aware that the "file" count is actually a count of the lines from ls less one. So if you have a pathological file name that contains a newline ls -l will count twice. Here we did this by including the -q flag (see man ls, GNU versions in particular)

4
  • Note that they are trying to avoid counting directories with grep -v /. If you're using external utilities, you could just as well do zsh -c 'set -- *(D^/); echo $#' (counts and outputs number of non-directories in the current directory, including hidden files (the D)).
    – Kusalananda
    Commented Sep 17 at 19:54
  • @Kusalananda oh is that what they're doing with that Commented Sep 17 at 21:44
  • a maybe better count of the number of entries : counting the number of: "-rwx.... nb_links" ? | awk '( $1 ~ "^[dlnspcb-][rwxXst-]{9}" && $2 ~ "^[1-9][0-9]*$" ) { sum+=1 }; END { print sum }' Commented Sep 18 at 15:51
  • @Kusalananda, more like zsh -c '(){echo $#} *(ND^/)' Commented Sep 18 at 15:54
0

In addition to Chris's good advice to use a function, Don't parse ls Use stat to get statistics about files:

lsfc() {
    ls -lq -- "$@"
    printf 'File count: %d\n' "$(stat -c '%F' "$@" | grep -cF 'regular file')"
}

GNU stat understands the -c option. Check your stat man page.

... Although, depending on your positional parameters, ls and stat may interpret "$@" differently.

1
  • 1
    lsfc is expected to get a list of directory paths and list their contents, but you're stating those directories instead of the files they contain. The OP's grep -v / also suggests they have an alias that adds the -F or -p option. Commented Sep 18 at 15:52

You must log in to answer this question.

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