私はbashスクリプトを学習しており、引数として指定されたディレクトリ内のファイルとディレクトリをカウントするスクリプトを作成しました。私は奇妙に思える1つの方法でそれを動作させており、それを行うより簡単な方法があるかどうか疑問に思っています。
動作するコードをコメントアウトしましたが、比較のために残しておきます。代わりにfor
- loopを機能させようとしていますが、代わりにif
ステートメントを使用して、指定された場所のアイテムがファイルかディレクトリかを検出しています。
編集:コメントされたコードは、指定された場所のサブディレクトリ内のすべてのファイルとディレクトリもカウントすることがわかりました!これを防ぎ、特定の場所のファイルとディレクトリを数えるだけの方法はありますか?
#!/bin/bash
LOCATION=$1
FILECOUNT=0
DIRCOUNT=0
if [ "$#" -lt "1" ]
then
echo "Usage: ./test2.sh <directory>"
exit 0
fi
#DIRS=$(find $LOCATION -type d)
#FILES=$(find $LOCATION -type f)
#for d in $DIRS
#do
# DIRCOUNT=$[$DIRCOUNT+1]
#done
#for f in $FILES
#do
# FILECOUNT=$[$FILECOUNT+1]
#done
for item in $LOCATION
do
if [ -f "$item" ]
then
FILECOUNT=$[$FILECOUNT+1]
Elif [ -d "$item" ]
then
DIRCOUNT=$[$DIRCOUNT+1]
fi
done
echo "File count: " $FILECOUNT
echo "Directory count: " $DIRCOUNT
何らかの理由で、for
- loopの出力は、場所をどこに指定しても、常に返されます。
File count: 0 , Directory count: 1
指定されたディレクトリ内のファイルのリストを繰り返し処理していません。 /*
の後に$LOCATION
を追加します。スクリプトは次のようになります。
...
for item in $LOCATION/*
do
...
Dogbaneが指摘したように、/*
を追加するだけで、.
で始まらないファイルのみがカウントされます。そのためには、次のことを行う必要があります。
...
for item in $LOCATION/* $LOCATION/.*
do
...
以下に示すようにfind
を使用します。このソリューションは、スペース、改行、ドットファイルを含むファイル名を正しくカウントします。
FILECOUNT="$(find . -type f -maxdepth 1 -printf x | wc -c)"
DIRCOUNT="$(find . -type d -maxdepth 1 -printf x | wc -c)"
DIRCOUNT
には現在のディレクトリ(.
)。これが望ましくない場合は、1を引きます。
((DIRCOUNT--)) # to exclude the current directory
問題を解決するために使用できます:
_FILECOUNT=$(find $LOCATION -type f | wc -l)
DIRCOUNT=$(find $LOCATION -type d | wc -l)
_
find
は、すべてのファイル(_-type f
_)またはディレクトリ(_-type d
_)を_$LOCATION
_の下で再帰的に検索します。 _wc -l
_は、それぞれの場合にstdoutに書き込まれた行数をカウントします。
ただし、学習したい場合は、bashスクリプトの方が適している場合があります。コメント:
$LOCATION
_のみでファイル/ディレクトリを検索する場合(サブディレクトリなどの下で再帰的ではない)、_for item in $LOCATION/*
_を使用できます。ここで、_*
_はファイル/ディレクトリのリストに展開されます。 _$LOCATION
_ディレクトリ内。欠落している_*
_が、元のスクリプトが0/1を返す理由です(_$LOCATION
_ディレクトリ自体がカウントされる唯一のアイテムであるため)。$LOCATION
_が実際に_[ -d $LOCATION ]
_を持つディレクトリであることを確認することをお勧めします。$(( ... ))
を使用します(例:FILECOUNT=$(( FILECOUNT + 1 ))
)。find
をループと組み合わせることができます。例:
_find $LOCATION | while read item; do
# use $item here...
done
_
... am wondering if there is a simpler way of doing it.
あなたがそう言うなら;)
または、スクリプトを
find /path/to/directory | wc -l
現在のディレクトリの場合:
find . | wc -l
使用する
find $LOCATION -maxdepth 1 -type f | wc -l
ファイルの数、および
find $LOCATION -maxdepth 1 -type d | wc -l
ディレクトリのカウント用