Объединение find
и awk
позволяет средние значения также должны быть вычислены:
find . -type f -printf '%s %h/%f\0'|awk 'BEGIN { RS="\0" } { SIZE=$1; for (i = 1; i <= NF - 1; i++) $i = $(i + 1); NF = NF - 1; DIR=$0; gsub("/[^/]+$", "", DIR); FILE=substr($0, length(DIR) + 2); SUMSIZES[DIR] += SIZE; NBFILES[DIR]++; if (SIZE > MAXSIZE[DIR] || !BIGGESTFILE[DIR]) { MAXSIZE[DIR] = SIZE; BIGGESTFILE[DIR] = FILE } }; END { for (DIR in SUMSIZES) { printf "%s: average %f, biggest file %s %d\n", DIR, SUMSIZES[DIR] / NBFILES[DIR], BIGGESTFILE[DIR], MAXSIZE[DIR] } }'
Сценарий AWK, изложенный более читаемым образом, имеет вид
BEGIN { RS="\0" }
{
SIZE=$1
for (i = 1; i <= NF - 1; i++) $i = $(i + 1)
NF = NF - 1
DIR=$0
gsub("/[^/]+$", "", DIR)
FILE=substr($0, length(DIR) + 2)
SUMSIZES[DIR] += SIZE
NBFILES[DIR]++
if (SIZE > MAXSIZE[DIR] || !BIGGESTFILE[DIR]) {
MAXSIZE[DIR] = SIZE
BIGGESTFILE[DIR] = FILE
}
}
END {
for (DIR in SUMSIZES) {
printf "%s: average %f, biggest file %s %d\n", DIR, SUMSIZES[DIR] / NBFILES[DIR], BIGGESTFILE[DIR], MAXSIZE[DIR]
}
}
. Он ожидает входных записей, разделенных нулем (я украл это из ответа Муру ); для каждой входной записи он
После этого сценарий перебирает ключи в SUMSIZES
и выводит каталог, средний размер, имя и размер самого большого файла.
Вы можете направить вывод в sort
для сортировки по имени каталога. Если вы хотите дополнительно отформатировать размеры в удобной для человека форме, вы можете изменить строку printf
на
printf "%.2f %d %s: %s\n", SUMSIZES[DIR] / NBFILES[DIR], MAXSIZE[DIR], DIR, BIGGESTFILE[DIR]
, а затем перенаправить вывод в numfmt --field = 1,2 --to = iec
. Вы все еще можете отсортировать результат по имени каталога, вам просто нужно отсортировать, начиная с третьего поля: sort -k3
.