bash 显示目录中文件和目录数的 Shell 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22472417/
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-10 00:44:07  来源:igfitidea点击:

Shell Script to Display Number of Files and Directories in a Directory

bashshellunixfind

提问by user1992348

I'm trying to write a script that will tell you how many files and how many directories are in a given directory.

我正在尝试编写一个脚本来告诉您给定目录中有多少文件和多少目录。

Here's the script I've written, but the output is always "Number of files is ." and "Number of directories is ."

这是我编写的脚本,但输出始终为“文件数为 .”。和“目录数是。”

Here's my code:

这是我的代码:

#!/bin/sh
if [ -d "$@" ]
then
find "$@" -type f | ls -l "$@" | wc -l | echo "Number of files is $@"
find "$@" -type d | ls -l "$@" | wc -l | echo "Number of directories is $@"
fi

采纳答案by Kevin

You seem to be confused on piping here.

你似乎对这里的管道感到困惑。

You want the output of find ... | wc -lto be expanded in the echocommand.

您希望find ... | wc -lecho命令中扩展的输出。

So, your script, given what you want to accomplish should look something like this:

因此,鉴于您要完成的任务,您的脚本应如下所示:

#!/bin/sh

if [ -d "$@" ]; then
    echo "Number of files is $(find "$@" -type f | wc -l)"
    echo "Number of directories is $(find "$@" -type d | wc -l)"
else
    echo "[ERROR]  Please provide a directory."
    exit 1
fi

回答by Adrian Frühwirth

You seem to be having difficulties to understand how pipes work. You cannot "natively" use the "result" (stdout) of a pipe (the left-hand side) as a variable on the right-hand side of a pipe, you either need to consume and read it into a variable, e.g.

您似乎很难理解管道的工作原理。您不能“本地”使用管道(左侧)的“结果”(stdout)作为管道右侧的变量,您要么需要使用它并将其读入变量,例如

printf "line1\nline2\n" | while read line; do_stuff_with "${line}"; done

or you need to use command substitution (and optionally assign it to a variable), e.g.

或者您需要使用命令替换(并可选择将其分配给变量),例如

files=$(find "" -maxdepth 1 -type f -printf . | wc -c)

A few further notes:

一些进一步的说明:

  • $@expands to all positional parameters, in case of multiple arguments your [ -d "$@" ]will fail.
  • The lsis completely superfluous
  • findworks recursively, but I guess you only want the first directory level to be checked so this needs the maxdepthparameter
  • This will break on weird paths with newlines which can be worked around by telling findto print a character for each found directory/file and then count bytes instead of lines
  • $@扩展到所有位置参数,如果有多个参数,您[ -d "$@" ]将失败。
  • ls完全是多余的
  • find递归工作,但我想你只希望检查第一个目录级别,所以这需要maxdepth参数
  • 这将在带有换行符的奇怪路径上中断,这可以通过告诉find为每个找到的目录/文件打印一个字符然后计算字节而不是行来解决

In case you really don't want this to be recursive it might be easier to just use globbingto obtain the desired result:

如果您真的不希望这是递归的,那么使用globbing来获得所需的结果可能会更容易:

$ cat t.sh
#!/bin/bash

for file in "${1-.}"/*; do
        [ -d "${file}" ] && ((directories++))
        [ -f "${file}" ] && ((files++))
done

echo "Number of files: ${files-0}"
echo "Number of directories: ${directories-0}"

.

.

$ ./t.sh
Number of files: 6
Number of directories: 1

$ ./t.sh /tmp
Number of files: 9
Number of directories: 3

You might want to check man testto tweak with regards to links to obtain your desired result.

您可能需要检查man test以调整链接以获得所需的结果。