ディレクトリツリーのファイル数の計算

ディレクトリツリーのファイル数の計算

バックアッププログラムの整合性チェックのために、サブディレクトリ、サブサブディレクトリなどのすべてのファイルを含むディレクトリ内のすべてのファイルを計算する機能を定義したいと思います。

これまでに試した解決策は次のとおりです。

countfiles() {
  local cdir=$1
  local files=$(ls -la $cdir | grep -cv '^[dl]')

  local dirstring=$(ls -la $cdir | grep '^d' | egrep -o ' \.?[^[:space:].][^[:space:]]+$')
  local directories=(${dirstring//"\n"/})

  echo ${directories[@]}


  for dir in ${directories[@]}; do
    echo -n "$dir "
    echo -n 'filecount >> '
    local dirfiles=$(countfiles "$cdir/$dir")
    echo -n $dirfiles
    echo ' <<'
    #files=$(($files+$dirfiles))
  done

  echo $files

}

これにより、次のような結果が得られます。

.config .i3 .scripts
.config filecount >> gtk-3.0 termite gtk-3.0 filecount >> 2 << termite filecount >> 2 << 1 <<
.i3 filecount >> 5 <<
.scripts filecount >> 2 <<
5

私のカウンターの実装には$filesatmというコメントがあり、ローカライズをオフにする必要があるかもしれませんが、今は干渉を避けるためにすべての変数をローカルにします。

ディレクトリツリーは次のとおりです。

/.scripts/backup_dotfiles.sh
/.config/termite/config
/.config/gtk-3.0/settings.ini
/.i3/config
/.i3/i3blocks.conf
/.i3/lockicon.png
/.i3/lockscreen.sh
/.gtkrc-2.0
/.bashrc
/.zshrc
/.i3
/.Xresources

私の質問:

  • ホームディレクトリ外のファイルはなぜ常に+1ですか?
  • ".config"ディレクトリにファイルがないのに、なぜそのディレクトリの内容を計算するのですか?
  • この問題をどのように解決できますか?

ベストアンサー1

findファイル名に改行文字がないと仮定した場合は、次のようにします。

find "$dir" -type f | wc -l

-type f通常のファイルと一致しますが、ディレクトリ、パイプ、ソケットなどとは一致しません。

通常の出力では、findファイル名を改行文字で区切るため、名前に改行文字が含まれていると出力があいまいになります。 GNU findを使用すると、次のように動作します。

find "$dir" -type f -printf . | wc -c

ファイルごとに1つのポイントのみを印刷し、findポイント数を計算します。

他のバージョンではfindそうではありませんが、-printfデュアルスラッシュを使用して入力パスを渡すトリックを使用できます。単一のスラッシュとして扱われますが、ファイル名にスラッシュを含めることはできないため、出力には自然には表示されません。次に、出力から二重スラッシュ数を計算します。

find "$dir//" -type -f | grep -c //

純粋にシェルスクリプトを使用してこれを行うには、シェルにファイル名を一覧表示するように要求できます。使用する必要はありませんls、たとえば、Bashでは次のようになります。

#!/bin/bash
files=0
shopt -s dotglob
countfiles() {
        local f;
        for f in * ; do 
                if [ -f "$f" ] ; then          # count regular files
                        files=$((files + 1))
                elif [ -d "$f" ] ; then        # recurse into directories
                        cd "$f"
                        countfiles
                        cd ..
                fi
        done
}
cd "$1"
countfiles
echo $files

おすすめ記事