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 scriptgrep -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"