16

私は bash スクリプトを学習しており、引数として指定されたディレクトリ内のファイルとディレクトリをカウントするスクリプトを作成しました。私には奇妙に思える1つの方法で動作していて、もっと簡単な方法があるかどうか疑問に思っています.

動作するコードをコメントアウトしましたが、比較のために残しました。指定された場所にあるアイテムがファイルまたはディレクトリであるかどうかを検出するために、ループ内のステートメントをfor使用する代わりに、ループを機能させようとしています。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、場所をどこに指定しても、ループの出力は常に次のように返されます。

File count: 0 , Directory count: 1
4

5 に答える 5

16

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
于 2012-12-05T16:19:26.870 に答える
14

問題を解決するには、次を使用できます。

FILECOUNT=$(find $LOCATION -type f | wc -l)
DIRCOUNT=$(find $LOCATION -type d | wc -l)

findの下にあるすべてのファイル ( -type f) またはディレクトリ ( -type d) を再帰的に検索します$LOCATIONwc -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
于 2012-12-05T15:58:14.100 に答える
5

指定されたディレクトリ内のファイルのリストを反復処理していません。/*の後に追加し$LOCATIONます。スクリプトは次のようになります。

...
for item in $LOCATION/*
do
...

dogbane で指摘されているように、追加するだけで;/*で始まらないファイルのみがカウントされます。.そのためには、次のことを行う必要があります。

...
for item in $LOCATION/* $LOCATION/.*
do
...
于 2012-12-05T15:58:00.773 に答える
3

... am wondering if there is a simpler way of doing it.

そう言えば(;_;)

または、スクリプトを次のように減らします。

find /path/to/directory | wc -l

現在のディレクトリについては、次のようにします。

find . | wc -l
于 2012-12-05T15:59:29.833 に答える
2

使用する

find $LOCATION -maxdepth 1 -type f | wc -l

ファイル数については、

find $LOCATION -maxdepth 1 -type d | wc -l

ディレクトリのカウント用

于 2012-12-05T16:06:38.933 に答える