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, 2024 at 12:38
  • 3
    I'd re-think your approach entirely - see for example How can I get a count of files in a directory using the command line? or What's the best way to count the number of files in a directory? Commented Sep 17, 2024 at 13:11
  • Many thanks to all for the help and advice!
    – David Shaw
    Commented Sep 25, 2024 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, 2024 at 19:54
  • @Kusalananda oh is that what they're doing with that Commented Sep 17, 2024 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, 2024 at 15:51
  • @Kusalananda, more like zsh -c '(){echo $#} *(ND^/)' Commented Sep 18, 2024 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, 2024 at 15:52

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.