Home > Net >  counting the number of files in a directory with a command line argument in bash
counting the number of files in a directory with a command line argument in bash

Time:09-21

I want to write a bash script such that it will count the number of files that exist in a directory. Furthermore it will need to accept a single command line argument which will be the directory path. I would also like it to print {directory} has {number of files} files.

e.g my_project has 3 files

I have tried ls /$@/ | wc -l which doesn't seem to work correctly

CodePudding user response:

You can count just the files in a specified directory using

ls -1F $dir_path | grep -v / | wc -l

where:

  • ls -1F $dir_path lists the files and folders within $dir_path

    -- -1 list one file per line

    -- -F append indicator to entries (one of */=>@|)

    -- $dir_path holds the argument passed to your script

  • grep -v / filters out the directories (if any)

  • wc -l counts the remaining lines which represents the files

In case you'd like to include hidden files - add the -A flag to ls.


The (basic) final script would look like so:
#!/bin/bash
# Set dir_path to current directory to support execution without arguments
dir_path="."
if [ $# -eq 1 ]; then
  dir_path="$1"
fi

num_of_files=$(ls -1F $dir_path | grep -v / | wc -l)

echo "Directory ${dir_path} have ${num_of_files} files."

CodePudding user response:

With bash, you can generate a string whose length is exactly the number of entries in a directory.

#!/usr/bin/env bash

count_entries() {
  # Count entries in current directory

  local -i dotglob=0 nullglob=0
  local -- all='' dirs=''

  # Save current settings
  shopt -q dotglob || dotglob=1
  shopt -q nullglob || nullglob=1

  # Need both globbing to count entries in directory
  shopt -s dotglob nullglob

  # Turn entries in directory into a string
  printf -v all -- '%.1s' *

  # Turn directory entries into a string
  printf -v dirs -- '%.1s' */

  # Restore settings
  [ "$dotglob" -eq 1 ] && shopt -u dotglob
  [ "$nullglob" -eq 1 ] && shopt -u nullglob

  # Number of entries are length of strings
  local -i a="${#all}"
  local -i d="${#dirs}"
  local -i f=$((a - d))

  # Print space delimited values
  printf '%d %d %d\n' "$a" "$d" "$f"
}

read -r entries directories files < <(count_entries)
printf 'In %s there are:\n%d entries\n%d directories\n%d files\n' "$PWD" \
  "$entries" "$directories" "$files"

CodePudding user response:

#!/bin/bash
set -e

shopt -s extglob
(($# == 1))
for p in "${1}/"?(.@([^.]|.?))*; do
  [[ -f "$p" ]] && ((  counter)) || :
done
printf '%s\n' "${path} has $((counter)) files"
  • Related