使用shell脚本计算文件和目录

Ala*_*ith 14 unix linux bash shell scripting

我正在学习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
Run Code Online (Sandbox Code Playgroud)

由于某种原因,for-loop 的输出,无论我指向哪个位置,总是返回:

File count: 0 , Directory count: 1
Run Code Online (Sandbox Code Playgroud)

dog*_*ane 14

使用find如下所示.此解决方案将正确计算带有空格,换行符和dotfiles的文件名.

FILECOUNT="$(find . -type f -maxdepth 1 -printf x | wc -c)"
DIRCOUNT="$(find . -type d -maxdepth 1 -printf x | wc -c)"
Run Code Online (Sandbox Code Playgroud)

请注意,DIRCOUNT包括当前目录(.).如果你不想要这个,减去1.

((DIRCOUNT--)) # to exclude the current directory
Run Code Online (Sandbox Code Playgroud)


And*_*son 12

要解决问题,您可以使用:

FILECOUNT=$(find $LOCATION -type f | wc -l)
DIRCOUNT=$(find $LOCATION -type d | wc -l)
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Rub*_*ens 5

您没有迭代给定目录中的文件列表; 添加/*之后$LOCATION.您的脚本应如下所示:

...
for item in $LOCATION/*
do
...
Run Code Online (Sandbox Code Playgroud)

正如dogbane指出的那样,只需添加/*将只计算不以的文件.; 为此,您应该执行以下操作:

...
for item in $LOCATION/* $LOCATION/.*
do
...
Run Code Online (Sandbox Code Playgroud)

  • 这是脚本中的实际主要问题. (2认同)