bash 如何获取文件夹中的文件数作为变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11131020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:17:26  来源:igfitidea点击:

How to get the number of files in a folder as a variable?

bashshell

提问by Jason

Using bash, how can one get the number of files in a folder, excluding directories from a shell script without the interpreter complaining?

使用 bash,如何获得一个文件夹中的文件数量,从 shell 脚本中排除目录,而没有解释器抱怨?

With the help of a friend, I've tried

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

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

which returns from the command line:

从命令行返回:

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

respectively. These commands work on the command line, but NOT with a bash script.

分别。这些命令在命令行上工作,但不适用于 bash 脚本。

Given a file filled with image files formatted like 1-pano.jpg, I want to grab all the images in the directory to get the largest numbered file to tack onto the next image being processed.

给定一个充满格式为 的图像文件的文件1-pano.jpg,我想抓取目录中的所有图像以获得最大编号的文件以添加到下一个正在处理的图像上。

Why the discrepancy?

为什么会出现差异?

回答by Paused until further notice.

The quotes are causing the error messages.

引号导致错误消息。

To get a count of files in the directory:

要获取目录中的文件数:

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

which creates an array and then replaces it with the count of its elements. This will include files and directories, but not dotfiles or .or ..or other dotted directories.

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

Use nullglobso an empty directory gives a count of 0 instead of 1.

使用nullglob这样的空目录给出的0而不是1计数。

You can instead use find -type for you can count the directories and subtract:

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

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

Also see "How can I find the latest (newest, earliest, oldest) file in a directory?"

另请参阅“如何在目录中找到最新(最新、最早、最旧)的文件?

You can have as many spaces as you want inside an execution block. They often aid in readability. The only downside is that they make the file a little larger and may slow initial parsing (only) slightly. There are a few places that must have spaces (e.g. around [, [[, ], ]]and =in comparisons) and a few that must not (e.g. around =in an assignment.

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

回答by mckenzm

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

One line.

一条线。

回答by Hai Vu

How about:

怎么样:

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

Note that this solution is not efficient: it spawns sub shells for the findand wccommands, but it should work.

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

回答by neam

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

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

this is a bit lightweight than a find command, and count all files of the current directory.

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

回答by fodger

Simple efficient method:

简单有效的方法:

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

回答by Bob

Get rid of the quotes. The shell is treating them like one file, so it's looking for "ls -l".

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

回答by Léa Gris

The most straightforward, reliable way I can think of is using the findcommand to create a reliably countable output.

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

Counting characters output of findwith wc:

计算findwith 的字符输出wc

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

or string length of the findoutput:

find输出的字符串长度:

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

or using findoutput to populate an arithmetic expression:

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

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

回答by kijana

REmove the qoutes and you will be fine

删除 qoutes,你会没事的

回答by Mike M

Expanding on the accepted answer (by Dennis W): when I tried this approach I got incorrect counts for dirs without subdirs in Bash 4.4.5.

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

The issue is that by default nullglob is not set in Bash and numdirs=(*/)sets an 1 element array with the glob pattern */. Likewise I suspect numfiles=(*)would have 1 element for an empty folder.

问题是默认情况下 nullglob 未在 Bash 中设置,而是numdirs=(*/)使用 glob 模式设置了一个 1 元素数组*/。同样,我怀疑numfiles=(*)一个空文件夹会有 1 个元素。

Setting shopt -s nullglobto disable nullglobbing resolves the issue for me. For an excellent discussion on why nullglob is not set by default on Bash see the answer here: Why is nullglob not default?

设置shopt -s nullglob禁用 nullglobbing 为我解决了这个问题。有关为什么在 Bash 上默认未设置 nullglob 的精彩讨论,请参阅此处的答案:Why is nullglob not default?

Note: I would have commented on the answer directly but lack the reputation points.

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

回答by Mike Q

Here's one way you could do it as a function. Note: you can pass this example, dirs for (directory count), files for files count or "all" for count of everything in a directory. Does not traverse tree as we aren't looking to do that.

这是您可以将其作为函数执行的一种方法。注意:你可以通过这个例子,dirs for (directory count),files for files count 或“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}
}

Examples of using the function :

使用函数的例子:

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

Will print something like :

将打印如下内容:

2
4
6