查找目录中每个扩展名的文件数

tra*_*boy 10 command-line extension find

我想计算目录中每个扩展名的文件数以及没有扩展名的文件数。

我尝试了几个选项,但还没有找到可行的解决方案:

  • find "$folder" -type f | sed 's/.*\.//' | sort | uniq -c是一个选项,但如果没有文件扩展名则不起作用。我需要知道有多少文件没有扩展名。

  • 我还尝试了一个 find 循环到一个数组中,然后对结果求和,但此时该代码抛出了一个未声明的变量错误,但仅在循环之外:

    declare -a arr
    arr=()
    echo ${arr[@]}
    
    Run Code Online (Sandbox Code Playgroud)

    这将抛出一个未声明的变量,一旦 find 循环完成。

0x2*_*fa0 11

find "$path" -type f | sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//' | LC_COLLATE=C sort | uniq -c
Run Code Online (Sandbox Code Playgroud)

解释:

  • find "$path" -type f 获取文件"$path"夹中所有文件的递归列表。
  • sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//' 常用表达:
    • /.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/ 用(无)替换所有没有扩展名的文件。
    • s/.*\.// 获取剩余文件的扩展名。
  • LC_COLLATE=C sort 对结果进行排序,将符号保持在顶部。
  • uniq -c 计算重复条目的数量。


Rav*_*ina 9

使用 Python:

import os
from collections import Counter
from pprint import pprint

lst = []
for file in os.listdir('./'):
        name, ext = os.path.splitext(file)
        lst.append(ext)

pprint(Counter(lst))
Run Code Online (Sandbox Code Playgroud)

输出:

Counter({'': 7,
         '.png': 4,
         '.mp3': 3,
         '.jpg': 3,
         '.mkv': 3,
         '.py': 1,
         '.swp': 1,
         '.sh': 1})
Run Code Online (Sandbox Code Playgroud)


ste*_*ver 6

如果你有 GNU awk,你可以做类似的事情

printf '%s\0' * | gawk 'BEGIN{RS="\0"; FS="."; OFS="\t"} 
  {a[(NF>1 ? $NF : "(none)")]++} 
  END{for(i in a) print a[i],i}
'
Run Code Online (Sandbox Code Playgroud)

即构造/递增以最后一个.分隔字段为键的关联数组,或一些任意固定字符串,例如(none)没有扩展名。

mawk似乎不允许使用空字节记录分隔符 -mawk如果您确信不需要处理文件名中的换行符,则可以使用默认的换行符分隔符:

printf '%s\n' * | mawk 'BEGIN{FS="."; OFS="\t"} {a[(NF>1 ? $NF : "(none)")]++} END{for(i in a) print a[i],i}'
Run Code Online (Sandbox Code Playgroud)


Ser*_*nyy 5

对于基本/bin/sh甚至bash任务可能有点困难,但正如您在其他答案中看到的那样,可以处理聚合数据的工具可以特别轻松地处理此类任务。一种这样的工具是sqlite数据库。

使用sqlite数据库的非常简单的过程是创建一个.csv包含两个字段的文件:文件名和扩展名。稍后sqlite可以使用简单的聚合语句COUNT()withGROUP BY ext来执行基于扩展字段的文件计数

$ { printf "file,ext\n"; find -type f -exec sh -c 'f=${1##*/};printf "%s,%s\n" "${1}" "${1##*.}"' sh {} \; ; }  > files.csv
$ sqlite3 <<EOF
> .mode csv
> .import ./files.csv files_tb
> SELECT ext,COUNT(file) FROM files_tb GROUP BY ext;
> EOF
csv,1
mp3,6
txt,1
wav,27
Run Code Online (Sandbox Code Playgroud)


Joe*_*oey 5

如果这是一个选项,则使用PowerShell

Get-ChildItem -File | Group-Object Extension -NoElement
Run Code Online (Sandbox Code Playgroud)

或更短,使用别名:

ls -file | group -n Extension
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。它已经存在一段时间了,跨平台和开源,但是在 SO 和 SU 上有一个模式,其中 Windows 上的 shell 脚本问题经常被回答为“好吧,安装 cygwin 并使用 bash,然后你可以执行以下操作”,所以我一直犹豫要不要使用源自 Windows 的工具对 Linux SE 站点做同样的事情。但这是一个很好的任务,它很好地展示了 PowerShell 的优势,而没有引起关于冗长的旧争论。 (2认同)