bash 列出带有文件计数的文件夹的 UNIX 命令

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

UNIX command to list folders with file counts

linuxbashunixshellcommand

提问by DisgruntledGoat

I want to get a list of folders at the current level (not including their subfolders) and simply print the folder name and a count of the number of files in the folder (preferably filtering to *.jpg if possible).

我想获取当前级别的文件夹列表(不包括它们的子文件夹),只需打印文件夹名称和文件夹中文件的数量(如果可能,最好过滤为 *.jpg)。

Is this possible in the standard bash shell? ls -lprints about everything but the file count :)

这在标准 bash shell 中可能吗?ls -l打印除文件计数之外的所有内容:)

回答by Johannes Schaub - litb

I've come up with this one:

我想出了这个:

find -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -maxdepth 1 -iname \*.jpg | wc -l)
    echo "$dir ; $count"
done

Drop the second -maxdepth 1if the search within the directories for jpg files should be recursive considering sub-directories. Note that that only considers the name of the files. You could rename a file, hiding that it is a jpg picture. You can use the filecommand to do a guess on the content, instead (now, also searches recursively):

-maxdepth 1如果考虑到子目录,在目录中搜索 jpg 文件应该是递归的,则删除第二个。请注意,这仅考虑文件的名称。您可以重命名文件,隐藏它是 jpg 图片。您可以使用该file命令对内容进行猜测(现在,也可以递归搜索):

find -mindepth 1 -maxdepth 1 -type d | while read dir; do 
    count=$(find "$dir" -type f | xargs file -b --mime-type | 
            grep 'image/jpeg' | wc -l)
    echo "$dir ; $count"
done

However, that is much slower, since it has to read part of the files and eventually interpret what they contain (if it is lucky, it finds a magic id at the start of the file). The -mindepth 1prevents it from printing .(the current directory) as another directory that it searches.

然而,这要慢得多,因为它必须读取文件的一部分并最终解释它们包含的内容(如果幸运的话,它会在文件的开头找到一个神奇的 id)。这会-mindepth 1阻止它打印.(当前目录)作为它搜索的另一个目录。

回答by Nicole

I found this question after I'd already figured out my own similar script. It seems to fit your conditions and is very flexible so I thought I'd add it as an answer.

在我已经想出我自己的类似脚本之后,我发现了这个问题。它似乎符合您的条件并且非常灵活,所以我想我会将其添加为答案。

Advantages:

好处:

  • can be grouped to any depth(0 for ., 1 for first level subdirectories, etc.)
  • prints pretty output
  • no loop, and only one findcommand, so it's a bit faster on large directories
  • can still be tuned to add custom filters (maxdepth to make it non-recursive, file name pattern)
  • 可以分组到任何深度(0 代表.,1 代表一级子目录等)
  • 打印出漂亮的输出
  • 没有循环,只有一个find命令,所以它在大目录上快一点
  • 仍然可以调整以添加自定义过滤器(maxdepth 使其非递归,文件名模式)

Raw code:

原始代码:

  find -P . -type f | rev | cut -d/ -f2- | rev | \
      cut -d/ -f1-2 | cut -d/ -f2- | sort | uniq -c

Wrapped into a function and explained:

包装成一个函数并解释:

fc() {
  # Usage: fc [depth >= 0, default 1]
  # 1. List all files, not following symlinks.
  #      (Add filters like -maxdepth 1 or -iname='*.jpg' here.)
  # 2. Cut off filenames in bulk. Reverse and chop to the
  #      first / (remove filename). Reverse back.
  # 3. Cut everything after the specified depth, so that each line
  #      contains only the relevant directory path
  # 4. Cut off the preceeding '.' unless that's all there is.
  # 5. Sort and group to unique lines with count.

  find -P . -type f \
      | rev | cut -d/ -f2- | rev \
      | cut -d/ -f1-$((${1:-1}+1)) \
      | cut -d/ -f2- \
      | sort | uniq -c
}

Produces output like this:

产生这样的输出:

$ fc 0
1668 .

$ fc # depth of 1 is default
   6 .
   3 .ssh
  11 Desktop
  44 Downloads
1054 Music
 550 Pictures

Of course with the number first it can be piped to sort:

当然,第一个数字可以通过管道传输到sort

$ fc | sort
   3 .ssh
   6 .
  11 Desktop
  44 Downloads
 550 Pictures
1054 Music

回答by m42

mine is faster to type from the command line. :)

我的从命令行输入速度更快。:)

do the other suggestions offer any real advantage over the following?

其他建议是否比以下建议有任何真正的优势?

find -name '*.jpg' | wc -l               # recursive


find -maxdepth 1 -name '*.jpg' | wc -l   # current directory only

回答by Dimitre Radoulov

You can do it without external commands:

您可以在没有外部命令的情况下执行此操作:

for d in */; do 
  set -- "$d"*.jpg
  printf "%s: %d\n" "${d%/}" "$#"
done

Or you can use awk(nawkor /usr/xpg4/bin/awkon Solaris):

或者您可以使用awk(在Solaris上为nawk/usr/xpg4/bin/awk):

printf "%s\n" */*jpg |
  awk -F\/ 'END { 
    for (d in _) 
      print d ":",_[d] 
      }
  { _[]++ }'

回答by John Ellinwood

#!/bin/bash
for dir in `find . -type d | grep -v "\.$"`; do
echo $dir
ls $dir/*.jpg | wc -l
done;