Есть файл вида
# IPFMv0.11.5 2009/01/24 03:00:00 (local time) -- dump every 1d00:00:00 -- listening on fxp0
# Host In (bytes) Out (bytes) Total (bytes)
relay 1173415529 110929187 1284344716
# end of dump 2009/01/24 03:00:00
Все хорошо но нужно чтоб было не в байтах а в кило/мега/гига байтах
залез в сырцы ipfm (data.c)- вроде нашел там структуры с полями in/out, но хз, правильно я там поделю, если б там еще комментарии были хоть какие-нибудь
Есть в инете скрипты на перле, но там куча всего ненужного, мне нужно одну строчку отформатировать и все.Просто в баше не силен, подскажите как
И чем перл неугодил? На перле, сохраняя разделители и меняя только цифры:
$ perl -pe 'use integer;$d=1024;$_=$1.($2/$d).$3.($4/$d).$5.($6/$d)."\n" if /^(\S+\s+)(\d+)(\s+)(\d+)(\s+)(\d+)$/;' <<eof
> # IPFMv0.11.5 2009/01/24 03:00:00 (local time) -- dump every 1d00:00:00 -- listening on fxp0
> # Host In (bytes) Out (bytes) Total (bytes)
> relay 1173415529 110929187 1284344716
> # end of dump 2009/01/24 03:00:00
> eof# IPFMv0.11.5 2009/01/24 03:00:00 (local time) -- dump every 1d00:00:00 -- listening on fxp0
# Host In (bytes) Out (bytes) Total (bytes)
relay 1145913 108329 1254242
# end of dump 2009/01/24 03:00:00
Как легко догадаться $d есть делитель, нужны мегабайты поставь $d=1024*1024
>Есть в инете скрипты на перле, но там куча всего ненужного, мне
>нужно одну строчку отформатировать и все.Просто в баше не силен, подскажите
>какВот вам быстренько и грязненько. Очень грязненько :-)
Сразу оговорюсь, что во-первых, этот скрипт "сломается" при обработке чисел больше 1 петабайта,
во-вторых, его можно сделать и компактнее, и красивее, а в-третьих, я этого делать не буду, ибо
мне оно не надо и лениво. :-)
$ cat file
# IPFMv0.11.5 2009/01/24 03:00:00 (local time) -- dump every 1d00:00:00 -- listening on fxp0
# Host In (bytes) Out (bytes) Total (bytes)
relay 1173415529 110929187 1284344716
# end of dump 2009/01/24 03:00:00$ cat script.sh
#!/bin/shhumanize()
{
var=$1
unit[1]="Kbytes"
unit[2]="Mbytes"
unit[3]="Gbytes"
unit[4]="Tbytes"
for ((i=1;i<=4;i++));
do
declare -i intvar=$(echo "$var" | awk -F '.' '{print $1}')
if [ $intvar -lt 1024 ]
then
echo "$var ${unit[$i]}"
break
else
var=$(echo "scale=2; $var/1024" | bc -l)
fi
done
}file=$1
cat "$file" | grep "^relay" | \
while read line;
do
IN=$(echo "$line" | awk '{print $2}')
OUT=$(echo "$line" | awk '{print $3}')
TOTAL=$(echo "$line" | awk '{print $4}')echo -n "In: "
humanize $INecho -n "Out: "
humanize $OUTecho -n "Total: "
humanize $TOTAL
done$ ./script.sh file
In: 1.09 Tbytes
Out: 105.79 Gbytes
Total: 1.19 Tbytes
И на том спасибо!
perl я имел ввиду что нашел целую большую прогу для обработки, а мне просто одну строчку менять надо
Ну так я вроде и дал однострочник на перле меняющий строки по регексу на то, что тебе надо. Если вдруг непонятно как использовать, то подавайте данные на stdin или укажите имя файла, а вывод перенаправляйте куда вам угодно. Альтернативно можно вызвать с ключом -i, тогда будет менять внутри файла, а не выводить на stdout, пример:
perl -i -pe 'use integer;$d=1024;$_=$1.($2/$d).$3.($4/$d).$5.($6/$d)."\n" if /^(\S+\s+)(\d+)(\s+)(\d+)(\s+)(\d+)$/;' somefile
>мне просто одну строчку менять надоВас удивляет, что bash - не совсем подходящий инструмент для?
>>мне просто одну строчку менять надо
>
>Вас удивляет, что bash - не совсем подходящий инструмент для?Как я уже сказал, я в баше не силен,поэтому я ничему не удивляюсь)
>>мне просто одну строчку менять надо
>
>Вас удивляет, что bash - не совсем подходящий инструмент для?Да вроде бы подходящий:
$ cat file
# IPFMv0.11.5 2009/01/24 03:00:00 (local time) -- dump every 1d00:00:00 -- listening on fxp0
# Host In (bytes) Out (bytes) Total (bytes)
relay 1173415529 110929187 1284344716
# end of dump 2009/01/24 03:00:00$ cat file | grep "^relay" | awk '{printf "%10.2f\t", $2/1024; printf "%10.2f\t", $3/1024; printf "%10.2f\n", $4/1024}'
1145913.60 108329.28 1254242.89 # Kbytes$ cat file | grep "^relay" | awk '{printf "%10.2f\t", $2/(1024*1024); printf "%10.2f\t", $3/(1024*1024); printf "%10.2f\n", $4/(1024*1024)}'
1119.06 105.79 1224.85 # Mbytes
Я, видимо, недостаточно внимательно прочел сообщение автора темы и решил, что ему требуется
привести данные в human-readable вид.P. S. К слову, в скрипте я допустил ошибку и он на порядок завышает единицу измерения - вместо
мегабайт пишет гигабайты и т. д. Функция humanize() должна выглядеть следущим образом:
humanize()
{
var=$1
unit[1]="Bytes"
unit[2]="Kbytes"
unit[3]="Mbytes"
unit[4]="Gbytes"
unit[5]="Tbytes"
for ((i=1;i<=5;i++));
do
declare -i intvar=$(echo "$var" | awk -F '.' '{print $1}')
if [ $intvar -lt 1024 ]
then
echo "$var ${unit[$i]}"
break
else
var=$(echo "scale=2; $var/1024" | bc -l)
fi
done
}
>>>мне просто одну строчку менять надо
>>Вас удивляет, что bash - не совсем подходящий инструмент для?"Удивляет" - было к "я просто хотел на баше[, а вы мне тут скриптовых языков]".
>Да вроде бы подходящий:
>$ cat file | grep "^relay" | awk '{printf ".2f\t", $2/1024; printfПод башем _я_ имел в виду баш. Как бы это ни было удивительно. Не "юниховый шелл скриптинг" вообще. Строку-таки у Вас меняет awk, не /bin/bash. На шелле можно было бы числа подставлять-переписывать-пересчитавыть... даже наверное без grep-ов-awk-ов, только это никому в голову не пришло -- все взяли "более подходящий инструмент".
>Под башем _я_ имел в виду баш. Как бы это ни было
>удивительно. Не "юниховый шелл скриптинг" вообще. Строку-таки у Вас меняет awk,
>не /bin/bash.Да уж, действительно удивили. :-)
Первоочередная задача shell - интерпретировать и выполнять команды, в том числе и команды
запуска внешних программ. Вот и запускает он у меня awk, который предназначен для работы с
текстом. Все же, как мне представляется, если человек пишет, что "в баше не
силен", то в виду имеется как раз "юниховый шелл скриптинг" а не "чистый shell".
>На шелле можно было бы числа подставлять-переписывать-пересчитавыть... даже наверное
>без grep-ов-awk-ов, только это никому в голову не пришло -- все
>взяли "более подходящий инструмент".И это, на мой взгляд, вполне естественно. Действительно, можно было бы обойтись без grep и awk,
но трудозатраты при этом были бы совершенно неоправданными. По крайней мере, для меня. :-)
Ну тогда вспомним, что perl в шелл скриптах такой же равноправный елемент как и awk/sed/grep итд, только значительно изящней, эффективней и надежней. Так что большинство заданий "написать шелл скрипт" можно свести к вызову перлового однострочника. Однако иногда для проверки сисадмина на знание шелла и способность программировать дают задание написать на чистом шелле, без вызова внешних программ, так что не стоит подобному удивляться.
>$ cat file | grep "^relay" | awk '{printf "%10.2f\t", $2/1024; printf
>"%10.2f\t", $3/1024; printf "%10.2f\n", $4/1024}'Можно ведь и покороче:
awk '{if($0~/^relay/){printf("%10.2f\t%10.2f\t%10.2f\n", $2/1024, $3/1024, $4/1024)}}' file
>>$ cat file | grep "^relay" | awk '{printf "%10.2f\t", $2/1024; printf
>>"%10.2f\t", $3/1024; printf "%10.2f\n", $4/1024}'
>
>Можно ведь и покороче:
>
>awk '{if($0~/^relay/){printf("%10.2f\t%10.2f\t%10.2f\n", $2/1024, $3/1024, $4/1024)}}' fileРазумеется, можно. :-)
Еще раз всем спасибо за горячий спор и работающие скрипты)