バックアッププログラムの整合性チェックのために、サブディレクトリ、サブサブディレクトリなどのすべてのファイルを含むディレクトリ内のすべてのファイルを計算する機能を定義したいと思います。
これまでに試した解決策は次のとおりです。
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
私のカウンターの実装には$files
atmというコメントがあり、ローカライズをオフにする必要があるかもしれませんが、今は干渉を避けるためにすべての変数をローカルにします。
ディレクトリツリーは次のとおりです。
/.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