如何将文件夹中的文件数作为变量?

时间:2012-06-21 03:09:12

标签: bash shell

使用bash,如何在没有解释器抱怨的情况下获取文件夹中的文件数,不包括shell脚本中的目录?

在朋友的帮助下,我试过了

$files=$(find ../ -maxdepth 1 -type f | sort -n)
$num=$("ls -l" | "grep ^-" | "wc -l")

从命令行返回:

../1-prefix_blended_fused.jpg: No such file or directory
ls -l :  command not found
grep ^-: command not found
wc -l:   command not found

分别。这些命令可以在命令行上运行,但不能使用bash脚本。

如果文件中填充的格式为1-pano.jpg的图像文件,我想获取目录中的所有图像,以获得最大编号的文件,以便处理下一个正在处理的图像。

为何出现差异?

10 个答案:

答案 0 :(得分:38)

引号导致错误消息。

获取目录中的文件数:

shopt -s nullglob
numfiles=(*)
numfiles=${#numfiles[@]}

创建一个数组,然后用它的元素计数替换它。这将包括文件和目录,但不包括dotfiles或...或其他虚线目录。

使用nullglob,因此空目录的计数为0而不是1。

您可以使用find -type f或者您可以计算目录并减去:

# continuing from above
numdirs=(*/)
numdirs=${#numdirs[@]}
(( numfiles -= numdirs ))

另见“How can I find the latest (newest, earliest, oldest) file in a directory?

您可以在执行块中拥有任意数量的空格。它们通常有助于提高可读性。唯一的缺点是它们会使文件变大,并且可能会稍微减慢初始解析(仅)。有几个地方必须有空格(比如[[[]]]=在比较中)和一些不得(例如,在作业中约为=

答案 1 :(得分:13)

ls -l | grep -v ^d | wc -l

一行。

答案 2 :(得分:12)

怎么样:

count=$(find .. -maxdepth 1 -type f|wc -l)
echo $count
let count=count+1 # Increase by one, for the next file number
echo $count

请注意,此解决方案效率不高:它会为findwc命令生成子shell,但它应该可以正常工作。

答案 3 :(得分:3)

file_num=$(ls -1 --file-type | grep -v '/$' | wc -l)

这比find命令稍微轻一些,并计算当前目录的所有文件。

答案 4 :(得分:1)

摆脱报价。 shell将它们视为一个文件,因此它正在寻找“ls -l”。

答案 5 :(得分:1)

简单有效的方法:

#!/bin/bash
RES=$(find ${SOURCE} -type f | wc -l)

答案 6 :(得分:1)

我能想到的最直接,最可靠的方法是使用find命令来创建可靠的可数输出。

find计算wc的字符输出:

find . -maxdepth 1 -type f -printf '.' | wc --char

find输出的字符串长度:

a=$(find . -maxdepth 1 -type f -printf '.')
echo ${#a}

或使用find输出填充算术表达式:

echo $(($(find . -maxdepth 1 -type f -printf '+1')))

答案 7 :(得分:0)

删除引号,你会没事的

答案 8 :(得分:0)

扩展已接受的答案(由Dennis W提出):当我尝试这种方法时,我在Bash 4.4.5中得到了没有子目录的dirs的错误计数。

问题在于,默认情况下,nullglob未在Bash中设置,numdirs=(*/)使用glob模式*/设置1个元素数组。同样地,我怀疑numfiles=(*)将有一个空元素的元素。

设置shopt -s nullglob以禁用nullglobbing可以解决我的问题。有关为什么默认情况下未在Bash上设置nullglob的优秀讨论,请参阅此处的答案:Why is nullglob not default?

注意:我会直接评论答案,但缺乏声誉点。

答案 9 :(得分:0)

这是您可以将其用作函数的一种方法。注意:您可以传递此示例,dirs用于(目录计数),files用于文件计数,或“ all”用于目录中所有内容的计数。不遍历树,因为我们不打算这样做。

function get_counts_dir() {

    # -- handle inputs (e.g. get_counts_dir "files" /path/to/folder)
    [[ -z "${1,,}" ]] && type="files" || type="${1,,}"
    [[ -z "${2,,}" ]] && dir="$(pwd)" || dir="${2,,}"

    shopt -s nullglob
    PWD=$(pwd)
    cd ${dir}

    numfiles=(*)
    numfiles=${#numfiles[@]}
    numdirs=(*/)
    numdirs=${#numdirs[@]}

    # -- handle input types files/dirs/or both
    result=0
    case "${type,,}" in
        "files")
            result=$((( numfiles -= numdirs )))
        ;;
        "dirs")
            result=${numdirs}
        ;;
        *)  # -- returns all files/dirs
            result=${numfiles}
        ;;

    esac

    cd ${PWD}
    shopt -u nullglob

    # -- return result --
    [[ -z ${result} ]] && echo 0 || echo ${result}
}

使用函数的示例:

folder="/home"
get_counts_dir "files" "${folder}"
get_counts_dir "dirs" "${folder}"
get_counts_dir "both" "${folder}"

将打印类似:

2
4
6
相关问题