Поиск и замена значения в текстовом файле (ака log file) [РЕШЕНО]
Здравствуйте уважаемые.
Прошу помощи. В BASH не силен, гуглил и не только, но вот решения не нашел.
Задача в следующем:
Имеются несколько ОГРОМНЫХ (под 100 Мб) текстовых логов одного из сервисов (не суть важно какого), в нем нужно поменять "цифровое" значение. Вот кусочек из этого "лог-а":
Fill_message:00FFACBH: primary_set=5609
Paper_message:FFH09BEB: secondary_set=1750
Так вот, не просто поменять цифру НО и значения после слов "primary_set=" и "secondary_set=" помножить к примеру на 2. Т.е. берем значение в primary_set=5609 умножаем его на 2 и получившийся ответ заменяем, и в итоге должно получится в логе:
Fill_message:00FFACBH: primary_set=11218
Paper_message:FFH09BEB: secondary_set=3500
Очень прошу помогите по существу. Обязуюсь потом все почитать, все маны и все доки что Вы посоветуете.
- Для комментирования войдите или зарегистрируйтесь

awk sed
awk sed
_SerEga_ написал(а): awk
в том то и дело что awk требует ПРОБЕЛА (разделителя) а вот после primary_set= нет пробела (разделителя) там С_Л_И_Т_Н_О... пробовал я, не выходит.
Тут надо как то цифру в переменную получить, помножив "положить обратно" измененную, переменную обнулить и т.д.
Нэ?
# echo 'Fill_message:00FFACBH: primary_set=5609' | awk -F = '{ print $2; }' 5609Поясняю. Ключ -F указывает awk, какой символ использовать в качестве разделителя. В данном случае это '='.
Я не смог понять твой комментарий...
И по этому поводу решил подарить тебе запятую: ",". Используй её с умом!
Несколько «коряво» и
Несколько «коряво» и сработает только, если файл выглядит так, как вы показали
% cat test.log Fill_message:00FFACBH: primary_set=5609 Paper_message:FFH09BEB: secondary_set=1750 lupo@gentoo-laptop Desktop % awk -F '=' '{print $1"="$2*2}' test.log Fill_message:00FFACBH: primary_set=11218 Paper_message:FFH09BEB: secondary_set=3500Я ♥ Gentoo & Funtoo
Lupo Alberto
Сек, проверю... возможно вы для меня совершили "ЧУДО"....
sed
Теперь я правильно сделаю если захочу заменить цифры и сохранить в файле вот таким образом:
sed -i 's/awk -F '=' '{print $1"="$2*2}''/ /test.log
Я же вам показывал, что
Я же вам показывал, что скрипт сразу выводит нужный результат:
awk -F '=' '{print $1"="$2*2}' test.log Fill_message:00FFACBH: primary_set=11218 Paper_message:FFH09BEB: secondary_set=3500Перенаправьте вывод в другой файл
awk -F '=' '{print $1"="$2*2}' test.log > new_test.logЯ ♥ Gentoo & Funtoo
Lupo Alberto написал(а): Я же
Да, я дико извиняюсь перед Вами, не совсем точно дал формат первичного лога, кроме этих двух строк идут масса других незначимых для моей задачи строк, вот "кусок" лога:
и т.п.
Так вот надо оставить значения
а эти заменить умножив на два
как итог должен получится следующий лог
Вот более «красивый»
Вот более «красивый» вариант:
awk -F '=' '$2=$2*2 {print $0}' test.log > new_test.logили даже так:
Я ♥ Gentoo & Funtoo
Lupo Alberto написал(а): Вот
он ЗНАЧЕНИЯ УДАЛЯЕТ а все остальное оставляет.
Попробуйте с этим лог-ом
после
awk -F '=' '$2=$2*2 {print $0}' test.log > new_test.logили:
остается
lupo@gentoo-laptop Desktop %
Я ♥ Gentoo & Funtoo
Lupo Alberto
Знак "=" - "улетает" почему то у меня вот что получается когда я точно так же делаю:
awk -F "=" '{ if (/_set/) { $2=$2*2; { print $0 } } else { print $0 } }' new.txt Oct 2 06:23:55 tangero spool_syst: targ=[ICH09BC] Oct 2 06:23:55 tangero spool_syst: TARGET, PARS=steel_one, tp=[MMCG], type=[10] Oct 2 06:23:55 tangero spool_syst: Fill_message:00FFACBH: primary_set 11218 Oct 2 06:23:55 tangero spool_syst: Paper_message:FFH09BEB: secondary_set 3500 Oct 2 06:26:12 tangero spool_syst: targ=[ICH09BD] Oct 2 06:26:12 tangero spool_syst: TARGET, PARS=steel_one, tp=[MMCE], type=[05] Oct 2 06:26:12 tangero spool_syst: Fill_message:00FFACCA: primary_set 13584 Oct 2 06:26:12 tangero spool_syst: Paper_message:FFH09BDC: secondary_set 3968Это я увлёкся оптимизацией
Это я увлёкся оптимизацией :)
Попробуйте так:
awk -F "=" '{ if (/_set/) { $2=$2*2; { print $1"="$2 } } else { print $0 } }' new.txtUPDATE: Опять не удержался от «оптимизации» :)
awk -F "=" '{ if (/_set/) { print $1"="$2*2 } else { print $0 } }' new.txtЯ ♥ Gentoo & Funtoo
ЗАРАБОТАЛО!!!
Заработало! Спасибо!!!
А вот у меня еще один лог есть, в нем "несколько" знаков "=":
В нем нужно изменить значение "outro=3737" также помножив его на 2.
Пытался Вашим выше-приведенным решением воспользоваться(перебирая местами переменными) у меня ничего не вышло =(.
Помогите еще раз пожалуйста. Я всю ночь не спал, логи "перебирал"... может из за этого уже в простых вещах путаться стал.
кажется пора в "разовую
кажется пора в "разовую работу" :)
Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)
slepnoga написал(а): кажется
Может быть... не спорю... сейчас у меня такое состояние, что я все путаю... сейчас вместо одной ложки кофе и одной ложки сахара намешал шесть ложек сахара и (ладно хоть с кофе не напутал) одну ложку кофе и еще соли присыпал... epic fail =(
slepnoga написал(а): кажется
В каждой шутке только доля шутки. :)
P.S. Хотелось бы увидеть образец лога и то, что должно получиться.
Я ♥ Gentoo & Funtoo
Lupo Alberto
ОК... спасибо что понимаете меня... и спасибо что помогаете...
Нужно изменить значение "outro=3737" помножив его на два.
Покажите больший кусок лога,
Покажите больший кусок лога, чтобы было несколько вхождений этого поля.
P.S. Если сделаю, то только к вечеру, пока занят.
Я ♥ Gentoo & Funtoo
Этот лог цикличен, дальше
Этот лог цикличен, дальше такой же кусок, только некоторые цифры и время изменено...
и т.д в таком духе
Есть тупой способ, но он
Есть тупой способ, но он работает.
1. Сначала отделяем кусок, который хотим менять, табуляцией:
cat test.log | sed 's/outro=\([0-9]*\)/outro=\t\1\t/'2. Потом этот кусок меняем как в примерах выше:
awk -F '\t' '{if($1~/outro=$/){$2=$2*2} print($0)}'3. После этого лишнюю табуляцию, которую поставили раньше, удаляем:
sed 's/outro=.\([0-9]*\)./outro=\1/'Итого вот скрипт:
cat test.log | sed 's/outro=\([0-9]*\)/outro=\t\1\t/' | awk -F '\t' '{if($1~/outro=$/){$2=$2*2} print($0)}' | sed 's/outro=.\([0-9]*\)./outro=\1/'P.S. если в изменяемой строке до "outro=" табуляция также присутствует, то вместо $2=$2*2 написать $3 и т.д.
andribas написал(а): Есть
Спасибо Вам, тоже вариант, если Lupo Alberto не отпишется, воспользуюсь Вашим вариантом, но способ от Lupo Alberto изящней чтоли =)
sidsoft67
Хы :)
Его способ явно быстрее - все в один проход делается, если и для этого случая есть такой способ - будет интересно посмотреть.
callisto /tmp $ awk '{
callisto /tmp $ awk '{if($8~/^outro=/) {split($8, a, "="); $8=a[1] "=" a[2]*2 ","; } print}' test Oct 1 03:24:43 asum metx/datx[12SDS]: HASTRU789: start Oct 1 03:24:43 asum metx/datx[12SDS]: HASTRU789: id=789 set=<AACH> Oct 1 03:24:43 asum metx/datx[12SDS]: HASTRU789: pid=<LINK_SETA> Oct 1 03:24:43 asum metx/datx[12SDS]: HASTRU789: int=<keep_liveurb>, outro=7474, hipp=ddach (systruct) Oct 1 03:24:44 asum metx/datx[12SDS]: HASTRU789: set=<LINK_SETA>, com_on=<id765544400CHH>, kimi_n=sign000000CGGHHEEEEXXXAAAXXXMMMM0000CHFG, port=ICH009BC, line=id789, open=1717, link=bit8 (opened) Oct 1 03:24:44 asum metx/datx[12SDS]: HASTRU789: stop Oct 1 03:25:11 asum metx/datx[12SDS]: HASTRU790: start Oct 1 03:25:11 asum metx/datx[12SDS]: HASTRU790: id=790 set=<AABH> Oct 1 03:25:11 asum metx/datx[12SDS]: HASTRU790: pid=<LINK_SETB> Oct 1 03:25:11 asum metx/datx[12SDS]: HASTRU790: int=<keep_liveurb>, outro=19702, hipp=ddbch (systruct) Oct 1 03:25:11 asum metx/datx[12SDS]: HASTRU790: set=<LINK_SETB>, com_on=<id9510511G0DHH>, kimi_n=sign000000CGGHHEEEEXXXAAAXXXMMMM0000CHFG, port=ICH009CC, line=id790, open=1719, link=bit8 (opened) Oct 1 03:25:11 asum metx/datx[12SDS]: HASTRU790: stopМожете обращаться, пишите в джаббер.
Lupo Alberto PLZ... Никак без
Lupo Alberto PLZ... Никак без тебя... =(
Попробуйте awk -F ", " '{ if
Попробуйте такой «костыль»
awk -F ", " '{ if (/outro/) {print $1", ""outro="substr($2,7)*2", "$3} else { print }}' log.txtP.S. «Перловоды» и «питонофилы» заходятся сейчас в нервном хохоте :)
Я ♥ Gentoo & Funtoo
БЛАГОДАРНОСТЬ!
Может и хохочут, но ЭТО работает. Реально РАБОТАЕТ!!! Спасибо тебе БОЛЬШОЕ Lupo Alberto, ты не только ВЫРУЧИЛ но и СПАС!!! Спасибо за понимание и не преувеличу если напишу что и за ДОБРОТУ, ОТЗЫВЧИВОСТЬ и ПОНИМАНИЕ.
Всем тем кто откликнулся тоже СПАСИБО и НИЗКИЙ ПОКЛОН Вам ребята!!!