使用bash迭代文件(和目录)名称

时间:2016-09-29 02:33:55

标签: linux bash shell unix

我正在尝试编写一个bash脚本来计算文件数和本地目录的目录数。这是我的第一次尝试:

#!/bin/bash
files=0
dir=0
for file in `ls`
do
    if [ -d $file ]
    then
        dir=$(($dir+1))
    else
        files=$(($files+1))
    fi
done 
echo "files=$files, direcotries=$dir"

但是,for命令并没有像我期望的那样迭代文件和目录的名称。如果文件ou目录的名称有空格,则不能正常工作。如果名称中有空格,则变量“file”将采用文件(或目录)名称中每个单词的值。

有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

使用外卡:for file in *; do …; done。这样可以保持名称中的空格正确。考虑shopt -s nullglob。您的代码和我的建议都不会列出以点.开头的名称。

另外,在变量值周围使用带有双引号的if [ -d "$file" ]以避免间距问题。

因此:

#!/bin/bash

shopt -s nullglob
files=0
dir=0
for file in *
do
    if [ -d "$file" ]
    then
        dir=$(($dir+1))
    else
        files=$(($files+1))
    fi
done 
echo "files=$files, directories=$dir"

在Bash中,还有其他编写算法的方法,例如((files++))

答案 1 :(得分:1)

我认为Jonathan Leffler的答案正是你所需要的。

显示bash数组功能的替代方案,无需循环:

shopt -s nullglob
dirs=(*/)
ndir="${#dirs[@]}"
files=(*)
nfile=$(( "${#files[@]}" - ndir))
echo "files=$nfile, directories=$ndir"

其工作原理如下:

  • dirs=(*/)创建一个目录名称数组。

  • ndir="${#dirs[@]}"计算目录数。

  • files=(*)创建所有文件和目录名称的数组。

  • nfile=$(( "${#files[@]}" - ndir))通过获取files的元素数并从中减去目录数来计算文件数。

  • echo "files=$nfile, directories=$ndir"打印出结果。

这只适用于支持数组的shell,比如bash。在许多系统上,shdash,它不支持数组。因此,在执行此脚本时使用bash script