2013-09-24 4 views
3

Прежде всего, я Баш нуб, поэтому, пожалуйста, быть нежным :)BASH: размер Сумма одноименных каталогов

Я пытаюсь подвести размер папки, которые находятся в разных местах, но имеют такое же имя , Это выглядит следующим образом:

root 
--- directory 1 

------ folder 1 
--------subfolder 1 
--------subfolder 2 
------ folder 2 
--------subfolder 3 
--------subfolder 4 
------ folder 3 
--------subfolder 5 
--------subfolder 6 

--- directory 2 

------ folder 1 
--------subfolder 1 
--------subfolder 2 
------ folder 2 
--------subfolder 3 
--------subfolder 4 
------ folder 3 
--------subfolder 5 
--------subfolder 6 

Я пытаюсь подвести размер подкаталогов 1 до 6, и вывод, что в .csv

На данный момент я просто выводя размеры подкаталогов в двух отдельных файлах CSV , Один для каталога 1 и один для каталога 2

На данный момент у меня есть это для вывода размеров subfodlers, что я бегу, где они нужны мне:

du -h --max-depth=1 --block-size=GB * | grep "[\/]" | sort -n -r > ~/lists/disks/RC_job.csv 

Выход выглядеть следующим образом:

40GB folder1/subfolder1 

15GB folder1/subfolder2 

10GB folder2/subfolder 3 
... 

У меня есть один вывод для каталога 1 и один для каталога 2. Я хотел бы суммировать размер подпапок из каталога один и два и иметь вывод, который выглядит следующим образом:

60GB subfolder1 

25GB subfolder2 

10GB subfolder3 

Где subfolder1 является directory1/folder1/subfolder1 + directory2/folder1/subfolder1

Это мой первый пост здесь, я не знаю, если это достаточно информации. Я был бы рад предоставить больше, если это необходимо. Я уверен, что это можно сделать с помощью awl, но я пока не использовал это.

Cheers!

Редактировать, чтобы ответить на вопрос в комментариях:

(Часть) выхода du -h /net/rcq-rp/job/rcq/vault/image/film /net/rcq-rp/job/rcq/film --max-depth=1 --block-size=GB * является:

1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0010 
1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0020 
1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0030 
1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0035 
1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0040 
1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0045 
2GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0050 
1GB /net/rcq-rp/job/rcq/vault/image/film/nr106/nr106_0060 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0010 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0020 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0030 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0035 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0040 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0045 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0050 
1GB /net/rcq-rp/job/rcq/film/nr106/nr106_0060 

В идеале конечный результат будет:

2GB nr106_0010 

etc... 
+0

Выберите текст и используйте инструмент '{}' в левом верхнем углу поля ввода редактирования, чтобы применить форматирование «Код образца» при необходимости. Пожалуйста, отредактируйте свой вопрос, чтобы включить примеры того, как будут выглядеть «дубликаты в 2-й колонке», и ваш необходимый результат для этого. Неясно, хотите ли вы добавить размер дубликатов и результаты вывода. Иллюстрации с фактическим входным и требуемым выходом (как вы уже начали делать!) Облегчат людям помощь. Удачи. – shellter

+0

Спасибо за совет. Это сделано, надеюсь, что это лучше! :) – titatom

+0

Зачем нужно иметь 'grep '[\ /]" '? – konsolebox

ответ

4

Один из способов сделать это с помощью ассоциативного массива. Ассоциативный массив отображает ряд ключей до значений, например:

directory1 -> 10 GB 
directory2 -> 12 MB 
directory3 -> 40 KB 

Ключи в ассоциативном массиве должны быть уникальными. Замечательно! Пути к нашим каталогам также уникальны. Поместим их в ассоциативный массив. Я покажу, как это сделать в awk, но на множестве других языков есть ассоциативные массивы (например, Perl, который называет их хэшами).

du | awk '{ val = $1; dir = $2; sizes[dir] = val }' 

(я вынул аргументы вы передаете du для простоты)

Что это делать?awk считывает вывод du по строкам; для каждой строки он добавляет элемент в ассоциативный массив sizes с именем каталога как индексом и размером в качестве значения. Если наш первоначальный вход выглядел как этот

40GB folder1/subfolder1 
15GB folder1/subfolder2 
10GB folder2/subfolder1 

наш массив будет выглядеть следующим образом:

sizes[folder1/subfolder1] -> 40GB 
sizes[folder1/subfolder2] -> 15GB 
sizes[folder2/subfolder1] -> 10GB 

Но в нашем окончательном выходе мы просто хотим, чтобы увидеть значения для подкаталогов. awk имеет функции для работы со строками, так что давайте подправить наш код, чтобы сдирать ведущие каталоги:

du | awk '{ val = $1; dir = $2; sub(/^.*\//, "", dir); sizes[dir] = val }' 

sub функция удаляет все от последнего / к началу пути. Теперь наш массив выглядит так:

sizes[subfolder2] -> 15GB 
sizes[subfolder1] -> 10GB 

Отлично! Теперь у нас есть только значения для подкаталогов. Есть только одна небольшая проблема. Значения не являются суммами. Поскольку у нас было более одного подкаталога с именем subfolder1, мы перезаписали первое значение (40 ГБ) со вторым (10 ГБ). Когда мы бежим в индекс, который уже существует в нашем массиве, что мы действительно хотим сделать, это добавить его значение к существующему значению:

du | awk '{ val = $1; dir = $2; sub(/^.*\//, "", dir); sizes[dir] += val }' 

(я изменил sizes[dir] = val, который использует назначение, чтобы sizes[dir] += val, который добавляет val к тому, что уже в sizes[dir])

awk волшебно заботится о некоторых вещах для нас, как преобразование 15 ГБ на номер 15. Теперь наш массив выглядит следующим образом:

sizes[subfolder2] -> 15 
sizes[subfolder1] -> 50 

, который показывает нам то, что мы ищем. Теперь, как это показать? Мы можем цикл по массиву и распечатать ключи и значения, как это:

du | awk '{ val = $1; dir = $2; sub(/^.*\//, "", dir); sizes[dir] += val } \ 
      END { for (dir in sizes) print dir, sizes[dir], "GB" }' 

и наши результаты

subfolder1 50 GB 
subfolder2 15 GB 

EDIT: Вот результаты я получаю с помощью du вывода в обновленном вопросе.

nr106_0060 2 GB 
nr106_0050 3 GB 
nr106_0045 2 GB 
nr106_0040 2 GB 
nr106_0035 2 GB 
nr106_0030 2 GB 
nr106_0020 2 GB 
nr106_0010 2 GB 
+0

Благодарим вас за это решение и отличное объяснение. Еще одна вещь: вложенная папка не находится в папке1 и папке2 находится в каталоге1/folder1 и directory2/folder1. У меня есть два раза, чтобы найти размер папок, которые я хочу суммировать. Однажды в каталоге1 и в другое время в каталоге2. Если я правильно понимаю, код, который вы объяснили, суммирует только папки, которые находятся в одном каталоге. Правильно ли я? Снова благодарим вас за помощь! – titatom

+0

@titatom Вы можете передать несколько аргументов в 'du', например. 'du dir1 dir2'. – ThisSuitIsBlackNot

+0

спасибо. Я попробую это прямо сейчас! – titatom

1

Я не уверен, сколько файлов csv вам понадобится в конце, но, возможно, это может помочь:

du -h --block-size=GB ./* | awk -F "[: \t/]" '{size[$NF] += $1} END {for (dir in size) print size[dir], dir}' | sort -n -r 

Команда size[$NF] += $1 суммирует размер (первый столбец), сохраняя результат в ассоциативном массиве, индексированном по имени каталога (последний столбец).

Смежные вопросы