2015-06-15 4 views
1

я смонтированный жесткий диск с несколькими пользователями, как это:Linux диск использование файлов, которые соответствуют выражению

/HDD1/user1 
/HDD1/user2 
/HDD1/user3 

Я хотел бы посмотреть в папке каждого пользователя, найти все файлы, которые совпадают с выражение (скажем, "*.txt"), а затем просуммировать пространство, используемое всеми этими файлами, и сообщить об этом на каждого пользователя базы:

user1: x bytes 
user2: y bytes 
user3: z bytes 

я нашел каталоги всех файлов с:

find /HDD1/ -name "*.txt" | rev | cut -d"/" -f2- | rev | uniq > txtfiles.dat 

Я думал, что использую цикл, чтобы пройти через каждую строку в txtfiles.dat, вычисляя использование диска в каждой папке, но это кажется очень громоздким. Есть ли более простой способ сделать это? Что-то вроде du, который выглядит в папке каждого пользователя, но только для подсчета файлов, соответствующих выражению?

+0

Подсказка: 'du -ac $ (find. -name '* .txt')' – Paul

ответ

1
find /HDD1/ -name "*.txt" -print0 | du -ch --files0-from - 

Объяснение: Команда find заботится о фильтрации набора файлов, и задание -print0 делает вывод NUL завершающим.

Выходной сигнал find подан на du. Задание --files0-from - указывает, что пути к файлам считываются в потоке с завершающим NUL из STDIN. Наконец, -ch инструктирует du, чтобы добавить общую общую строку, в удобной для восприятия форме.

Если все, что вы хотите, это общее, вы можете трубы результат для tail -1:

find /HDD1/ -name "*.txt" -print0 | du -ch --files0-from - | tail -1 
+0

Это будет общее количество в каждом поддиректоре HDD1 или общей сумме? – James

+0

@James: Это даст общую сумму в пределах HDD1, но вы можете легко обернуть ее в цикл 'for', чтобы вычислить сумму для каждого каталога. – voithos

2

du принимает список, и размер отдельных файлов, если предоставляется возможность -a и производить в общей сложности с возможностью -c ,

В оболочке bash $(cmd) - результат работы cmd.

Таким образом, поставив все вместе, чтобы получить размеры всех файлов .txt, можно запустить:

du -ac $(find . -name '*.txt')

1

Вы можете Переберите каждого пользователя и суммировать размеры примерно так:

for username in `ls /HDD1/`; do 
    find $username -iname *.txt -printf '%s\n' | awk '{s+=$1}END{print s}' - 
done 

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

+0

Должно ли это быть в bash? Я использую zsh в данный момент (но при необходимости может легко меняться). Я смущен, когда в код входит переменная '' 'username'''. – James

+0

вы забыли каталог arg, чтобы найти. также -printf нуждается в новой строке в формате. – meuh

+0

Я не знаю zsh, но единственная вещь bash - for-loop, поэтому вы можете легко ее преобразовать. Я забыл поместить $ username в find, благодаря @meuh для этого! Тем не менее, -printf не нуждается в новой строке, поскольку он входит в awk, и awk просто нуждается в каких-либо пробелах. – fahhem

1

Команда find (в большинстве систем) может печатать размер файла в байтах. Затем вы можете просто суммировать это, например, с awk.

for userdir in /HDD1/* 
do find "$userdir" -type f -name '*.txt' -printf '%s\n' | 
    awk -v u=$(basename "$userdir") ' 
     {tot+=$1} 
     END{print u ": " tot " bytes"} 
    ' 
done 

Это обеспечивает формат вывода, который вы запросили (user1: x bytes). Если количество байтов немного велико, разделите их на 1000 или 1024, чтобы получить килограмм или килобайт байтов и т. Д. (В awk print tot/1000 вместо tot).

0

я стягиваются биты и куски из всех ответов на это:

for n in /HDD1/* 
    do 
    uname=$(echo $n | cut -d'/' -f4) 
    space=$(find /HDD1/$uname -name "*.txt" -print0 | du -ch --files0- from - | tail -1) 
    echo $uname: $space 
done 

который, кажется, работает хорошо. Спасибо за все Ваши ответы.