16

我正在学习 bash 脚本并编写了一个脚本来计算作为参数提供的目录中的文件和目录。我让它以一种对我来说似乎很奇怪的方式工作,我想知道是否有一种更简单的方式来做到这一点。

我已经注释掉了可以工作的代码,但将其保留为比较。我试图让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
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

但是,如果您想学习,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 回答