Найдите количество файлов для каждого расширения в каталоге

Я хочу считать количество файлов для каждого расширения в каталоге, а также файлов без расширения.

Я попробовал несколько опций, но я еще не нашел рабочее решение:

  • find "$folder" -type f | sed 's/.*\.//' | sort | uniq -c опция, но не работает, если нет никакого расширения файла. Я должен знать, сколько файлы не имеют расширением.

  • Я также попробовал цикл находки в массив и затем суммирую результаты, но в это время, которые кодируют, бросает необъявленную переменную погрешность, но только за пределами цикла:

    declare -a arr
    arr=()
    echo ${arr[@]}
    

    Это бросает необъявленную переменную, а также после того как цикл находки завершается.

9
задан 3 September 2018 в 11:16

5 ответов

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

Объяснение:

  • find "$path" -type f получите рекурсивный список всех файлов на "$path" папка.
  • sed -e '/.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/' -e 's/.*\.//' регулярные выражения:
    • /.*\/[^\/]*\.[^\/]*$/!s/.*/(none)/ замените все файлы без расширения (ни одним).
    • s/.*\.// получите расширение остающихся файлов.
  • LC_COLLATE=C sort отсортируйте результат, сохранив символы наверху.
  • uniq -c считайте количество повторных записей.
9
ответ дан 16 November 2019 в 06:02

Использование 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))

Вывод:

Counter({'': 7,
         '.png': 4,
         '.mp3': 3,
         '.jpg': 3,
         '.mkv': 3,
         '.py': 1,
         '.swp': 1,
         '.sh': 1})
9
ответ дан 16 November 2019 в 06:02

Если у Вас есть 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}
'

т.е. создайте / увеличивают ассоциативный массив, включил последнее . разделенное поле или некоторая произвольная фиксированная строка такой как (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}'
6
ответ дан 16 November 2019 в 06:02

С основным /bin/sh или даже bash задача может быть немного трудной, но поскольку Вы видите в других ответах инструменты, которые могут работать над агрегированными данными, может иметь дело с такой особенно легкой задачей. Один такой инструмент был бы sqlite база данных.

Очень простой процесс для использования sqlite база данных должна была бы создать a .csv файл с двумя полями: имя файла и расширение. Позже sqlite может использовать простой совокупный оператор COUNT() с GROUP 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
5
ответ дан 16 November 2019 в 06:02

Используя PowerShell, если это - опция:

Get-ChildItem -File | Group-Object Extension -NoElement

или короче, использование псевдонимов:

ls -file | group -n Extension
5
ответ дан 16 November 2019 в 06:02

Другие вопросы по тегам:

Похожие вопросы: