Intereting Posts
Как проверить, какой клиент обращается к Unix? Удалите только одно слово перед совпадением шаблона в сценарии оболочки загрузочные метки и сектора Как сделать файлы, созданные определенным пользователем, для получения определенных разрешений по умолчанию Прослушать атрибуты RADIUS, отправленные одноранговому узлу Отправка почты из скрипта, который запускается Crontab Как обновить Kali Linux Поиск списка модулей, которые используются во время загрузки Настройте графическую панель Wacom Intuos в Linux Mint 15 Среднее значение и дисперсия произнесенных слов Какова первая восьмеричная цифра chmod в четырехзначном значении? перемещение Linux на другое устройство Недопустимый вход суффикса numfmt Beaglebone: резервное изображение монтирует root как только для чтения показать часть развязанных линий в vim вместо того, чтобы скрывать ее с символом @

Parse du result используя sed

Здравствуйте, я пытаюсь разобрать результат команды du, но я не знаю, как это сделать без циклов

du -shm /var/vmail/mailboxes/domain/*/mail 

мой результат – список, например:

 80 /var/vmail/mailboxes/domain/USER1/mail 150 /var/vmail/mailboxes/domain/USER2/mail 220 /var/vmail/mailboxes/domain/USER3/mail 

В приведенном выше списке я хочу преобразовать его в объект JSON с ниже:

 {USER1: 80, USER2:150, USER3:220 } 

или хотя бы иметь что-то

 80 USER1 150 USER2 220 USER3 

Я попробовал с sed -e но безуспешно, есть идеи?

 du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' '{ print $1, $7 }' 

С вводом от du в формате, который вы даете, это будет производить

 80 USER1 150 USER2 220 USER3 

Программа awk просто выбирает соответствующие поля из вывода du . Каждая строка интерпретируется как поля, разделенные пробелами или косой чертой.

awk -F '[ /]' '{ print $1, $(NF - 1) }' также будет работать.

Чтобы получить это в JSON, используя jq :

 du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' '{ print $1, $7 }' | jq -sR 'split("\n")[0:-1] | map(split(" ")) | map({(.[1]):.[0]}) | add' 

Это произведет

 { "USER1": "80", "USER2": "150", "USER3": "220" } 

Выражение jq сначала разбивает входные данные на отдельные элементы массива (по одному на строку ввода), а затем снова разбивает их по пробелам на подмассивы. На данный момент мы имеем

 [ [ "80", "USER1" ], [ "150", "USER2" ], [ "220", "USER3" ] ] 

После этого создаются объекты со вторым элементом в каждом подмассиве в качестве ключа и первым в качестве значения:

 [ { "USER1": "80" }, { "USER2": "150" }, { "USER3": "220" } ] 

add в конце дает нам окончательный результат.

пытаться

 du -sm /var/vmail/mailboxes/domain/*/mail | sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' 

где

  • s:/mail:: заменяет /mail ничем

пойти в JSON

 du -sm /var/vmail/mailboxes/domain/*/mail | sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' | awk 'BEGIN { sep="{" ;} { printf "%s \"%s\":%s",sep,$2,$1; sep="," } END { printf "}\n"}' 

Вы можете использовать awk для преобразования в формат с двумя столбцами:

 $ du -shm | awk -F/ '{print $1" "$(NF - 1)}' 80 USER1 150 USER2 220 USER3 

Для JSON попробуйте:

 $ du -shm | awk -F/ '{print "\""$(NF - 1)"\":"$1}' | paste -sd, | printf "{$(cat)}" | jq { "USER1": 80, "USER2": 150, "USER3": 220 } 

jq хорошо работает с необработанным текстом, то есть с флагом -R , например:

 du -sm /var/vmail/mailboxes/domain/*/mail | jq -R ' split(" ") | .[0] as $size | # Remember size .[1] | split("/") | .[-2] as $name | # Extract username { ($name) : ($size) } # Compose object ' 

Дает тебе:

 { "USER1": "80" } { "USER2": "150" } { "USER3": "220" } 

Чтобы объединить объекты, используйте второй вызов jq :

 ... | jq -s add 

Выход:

 { "USER1": "80", "USER2": "150", "USER3": "220" } 

Или в компактном режиме:

 ... | jq -sc add 

Выход:

 {"USER1":"80","USER2":"150","USER3":"220"} 

Это немного сложно сделать с sed . Тем не менее, вот прокомментированное предложение, которое работает с GNU sed:

parse.sed

 s|([^ ]+) .*/([^/]+)/.*| "\2" : \1,| # Extract size and name in json-format 1h; 1!H # Correctly add them to hold-space $ { z # Clear pattern-space s/^/\{/ # Prepend start-curly-brace G # Fetch formatted json from hold-space s/,$// # Remove last comma s/$/\n\}/ # Append end-curly-brace p # Print } 

Запустите это так:

 du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed 

Или как однострочник:

 du -shm /var/vmail/mailboxes/domain/*/mail | sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "\2" : \1,|;1h;1!H;${z;s/^/\{/;G;s/,$//;s/$/\n\}/;p}' 

Вывод в обоих случаях:

 { "USER1" : 80, "USER2" : 150, "USER3" : 220 }