В awk, как я могу увеличить индекс массива, когда он встречает новую строку? - PullRequest
2 голосов
/ 19 апреля 2020

Я пытаюсь проанализировать вывод ls (я знаю, что он недоволен, но мне нужно для назначения.) Мне нужно подсчитать количество каталогов для каждого пользователя и распечатать его под своим именем.

У меня есть для l oop, чтобы распечатать имена пользователей / количество каталогов:

for (users in uid){ 
       x++
       totalUsers++;
       printf("User: %s\n", users);


       if(dirs[x]>0)
        printf("   dirs: %s\n", dirs[x]);

    } 

И я пробовал это:

if(dirs[x] < $2) {
    dirs[x]=$2  
    x++
}

, но это победило ' t связать количество каталогов с полем пользователя.

По сути, я пытаюсь получить вывод:

user: mce237

   files:

   all/hidden: ( 52 / 12 )

   dirs: 4

   file storage: 2729344 B

из этого:

-rw-------  1 mce237 students     199 2020-03-01 18:41:59 .build1276786824731864129.log

-rw-------  1 mce237 students     199 2020-03-01 20:18:42 .build291177188595028335.log

-rw-------  1 mce237 students     199 2020-03-01 20:10:44 .build4195866878600813549.log

-rw-------  1 mce237 students     199 2020-03-01 20:08:55 .build4503681510908034369.log

-rw-------  1 mce237 students     199 2020-03-01 18:18:44 .build4964061885086964943.log

-rw-------  1 mce237 students     199 2020-03-01 20:17:13 .build5474334865226720725.log

-rw-------  1 mce237 students     199 2020-03-01 19:08:39 .build6322670020019345604.log

-rw-------  1 mce237 students     420 2020-03-01 20:08:08 .build8057453026527719771.log

1 Ответ

4 голосов
/ 19 апреля 2020

Вы можете проиндексировать все на user ($3), а затем сохранить отдельные массивы для каждого из количеств, которые необходимо отслеживать. Вы можете проверить, является ли первый символ в первом поле 'd', чтобы определить, является ли файл каталогом, и вы можете проверить, является ли первый символ в имени файла '.', чтобы определить, является ли файл скрытым (решать вам. если вы хотите подсчитать каждый каталог в итоговой сумме для пользователя - если нет, добавьте и else)

Чтобы отслеживать каждое из количеств и затем выводить в правиле END, вы можете сделать что-то аналогично:

ls -youroptions | awk '{
    user[$3]++
    storage[$3]+=$5
    if ($1 ~ /^d/)
        dir[$3]++
    if ($8 ~ /^[.]/)
        hidden[$3]++
}
END {
    for (i in user) 
        printf "user: %s\nfiles:\n(all/hidden): (%d/%d)\ndirs: %d\nstorage: %ld\n",
        i,user[i],hidden[i],dirs[i],storage[i]
}'

( примечание: при разборе ls вы, вероятно, захотите добавить NR > 1 {...}, чтобы избежать строки "total", напечатанной в качестве 1-й строки, - и другие параметры и настройки LOCALE могут привести к тому, что поля полей будут отличаться от показанных вами)

Пример вывода

Использование списка, предоставленного вами в качестве ввода (при условии, что на самом деле у вас нет пустого поля) строк между каждой строкой (ls output), будет получен следующий вывод:

user: mce237
files:
(all/hidden): (8/8)
dirs: 0
storage: 1813

Это должно показать вам один подход к обработке различных значений в отдельных массивах. с помощью общего поля в качестве индекса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...