Подскажите с tr

Программирование на sh, быть может немного про альтернативные языки
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-03 10:36:15

Добрый день.

Есть лог файл который необходимо обработать соотвествующим образом.
В логе есть нечто такое:

Код: Выделить всё

"слово1\слово2"
Необходимо преобразовать в

Код: Выделить всё

"слово1","слово2"
Т.е. по сути символ \ заменить на сочетание символов ",".
Погуглив нашел что это может сделать tr но кавычки "" это вроде как спецсимвол и сделать замену на такое сочетание символов не получается.
Подскажите пожалуйста как правильно сделать такое преобразование ?

Пробовал делать так:

Код: Выделить всё

tr \ \"\,\" 
В результате получаю так "слово1"слово2" - что меня не устраивает ...

Заранее спасибо за помощь.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

rmn
старшина
Сообщения: 427
Зарегистрирован: 2008-10-03 18:52:02

Re: Подскажите с tr

Непрочитанное сообщение rmn » 2011-05-03 11:31:48

Код: Выделить всё

awk -F\\ '{print $1"\",\""$2}'

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-03 12:01:14

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

Вся конструкция выглядит так:

Код: Выделить всё

gawk '{FS="[ ]+"} {print "INSERT INTO .....VALUES (" ..... ,\""$2"\", .... ,\""$14"\", .....} '  |  tr \ \"\,\" > /file
Вот в $14 содержится то что я хотел преобразовать при помощи tr, если возможно через awk или gawk подскажите пожалуйста как ?

Аватара пользователя
FreeBSP
майор
Сообщения: 2020
Зарегистрирован: 2009-05-24 20:20:19
Откуда: Москва

Re: Подскажите с tr

Непрочитанное сообщение FreeBSP » 2011-05-03 12:04:36

дай десяток-другой строк из лога
Человек начинает получать первые наслаждения от знакомства с unix системами. Ему нужно помочь - дальше он сможет получать наслаждение самостоятельно ©
Ламер — не желающий самостоятельно разбираться. Не путать с новичком: ламер опасен и знает это!

rmn
старшина
Сообщения: 427
Зарегистрирован: 2008-10-03 18:52:02

Re: Подскажите с tr

Непрочитанное сообщение rmn » 2011-05-03 12:10:10

kharkov_max писал(а):awk не годится т.к. awk уже используется для преобразования, разве что если можно как то вложенный awk использовать
в awk есть функция sub для замены подстрок

можно и так, если в строке только один символ \ (тот, что нужно заменить):

Код: Выделить всё

gawk '{FS="[ ]+"} {print "INSERT INTO .....VALUES (" ..... ,\""$2"\", .... ,\""$14"\", .....} '  |  awk -F\\ '{print $1"\",\""$2}' > /file

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-03 15:58:21

rmn писал(а):
kharkov_max писал(а):awk не годится т.к. awk уже используется для преобразования, разве что если можно как то вложенный awk использовать
в awk есть функция sub для замены подстрок

можно и так, если в строке только один символ \ (тот, что нужно заменить):

Код: Выделить всё

gawk '{FS="[ ]+"} {print "INSERT INTO .....VALUES (" ..... ,\""$2"\", .... ,\""$14"\", .....} '  |  awk -F\\ '{print $1"\",\""$2}' > /file
Вы правы в принципе так должно работать ... Что то не додумался до этого ...
Но !!!

Цель деления $14 было получить $14 (слово1) и $15 (слово2), но по определенным причинам $14 может быть изначально пустым - символ "-".
Вот тут как то нужно $14 делить в любом варианте на $14 и $15 с пустыми значениями или с каким нить символом, хотя бы "-".
Т.е. что б в /file получилось "-","-" -> ($14,$15) из первичного $14 ...

kpp
лейтенант
Сообщения: 613
Зарегистрирован: 2009-08-05 16:10:46
Откуда: Украина Днепропетровск-Киев
Контактная информация:

Re: Подскажите с tr

Непрочитанное сообщение kpp » 2011-05-03 21:35:51

Дайте лог посмотреть, а то так пальцем в небо.
Нет, ребята, я не гордый. Не загадывая вдаль, так скажу: зачем мне орден? Я согласен на медаль.

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 10:02:47

kpp писал(а):Дайте лог посмотреть, а то так пальцем в небо.
Вот:

Код: Выделить всё

1304491986.626      1 - 192.168.0.1 192.168.0.1 1864 - TCP_HIT 200 333 799 1132 http://forum.lissyara.su/styles/prosilver/theme/medium.css DOMAIN\user text/css 1.1 GET
1304492037.197      1 - 192.168.0.2 proxy1 49018 - TCP_MISS 200 6649 57 6706 cache_object://localhost/active_requests - text/plain 1.0 GET
Не буду скрывать, это лог Squid - пишу свой анализатор через Mysql.
Уже все работает и пишется в Mysql, так же есть универсальная процедура которая может выбирать из базы любые данные.
Единственная проблема это как правильно разделить DOMAIN\user указать домен в конфиге Squid нельзя, т.к. домена 2 (squid обслуживает 2 домена).
Лепить данное разделение в Mysql не хочу, хочу разделить на уровне парсинга лога т.е. через shell.
1я строка лога это с авторизацией, 2я там где поле DOMAIN\user пустое = "-".

Еще раз спасибо за помощь.

rmn
старшина
Сообщения: 427
Зарегистрирован: 2008-10-03 18:52:02

Re: Подскажите с tr

Непрочитанное сообщение rmn » 2011-05-04 11:40:25

parselog.sh

Код: Выделить всё

#!/bin/sh

while read a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17
do
    domain=""
    user=""

    if [ "$a14" != "-" ];
    then
        echo $a14 | awk -F\\ '{print $1,$2}' | read domain user
    fi

    echo "INSERT INTO ... (... , $domain, $user, ...)"
done

Код: Выделить всё

% cat squid.log | parselog.sh > file

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 11:51:22

Спасибо.

Тоже думал про такую схему, но пугал цикл.
Хотелось меньше комп грузить при парсинге, да и скорость отработки увеличить, но похоже придется переписать скрипт как Вы предложили.

rmn
старшина
Сообщения: 427
Зарегистрирован: 2008-10-03 18:52:02

Re: Подскажите с tr

Непрочитанное сообщение rmn » 2011-05-04 11:56:06

kharkov_max писал(а): Хотелось меньше комп грузить при парсинге, да и скорость отработки увеличить
такой вариант как раз будет быстрее и меньше будет систему нагружать, потому что строка будет разбиваться на составляющие встроенной функцией, а не внешней программой.

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 12:45:33

while read гасит разделитель "\" из лога.
Т.е. в логе $14 = DOMAIN\user в цикл while попадает как DOMAINuser соответственно вся остальная конструкция не работает.

Если в логе разделитель поправить на \\ то в цикл попадает как нужно в виде DOMAIN\user.

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 13:21:53

Конструкция вида

Код: Выделить всё

echo $a14 | read domain
echo $a14 $domain
Не работает ((( $domain пустой ...

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 16:20:22

Если интерестно, то решил эту задачу так:

Код: Выделить всё

$gawk '{FS="[ ]+"}
        {if ($14 != "-") { split($14,a,"\\");
                   print "INSERT INTO log .........
                   VALUES ("strftime("%Y%m%d%H%M%S",$1)",\""$2"\",\""$3"\", \
                   \""$4"\",\""$5"\","$6",\""$7"\",\""$8"\","$9","$10","$11","$12",\""$13"\",\""a[1]"\",\""a[2]"\", \
                   \""$15"\",\""$16"\",\""$17"\");"; }
               else { d="-";u=$14;
                   print "INSERT INTO log .....
                   VALUES ("strftime("%Y%m%d%H%M%S",$1)",\""$2"\",\""$3"\", \
                   \""$4"\",\""$5"\","$6",\""$7"\",\""$8"\","$9","$10","$11","$12",\""$13"\",\""$14"\",\""$14"\", \
                   \""$15"\",\""$16"\",\""$17"\");" }
         }' $squid_log_file > $tmp_file
Самый красивый вариант ))).
gawk - жжот ...

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 16:31:09

http://www.math.spbu.ru/user/rus/cluste ... glav.shtml - рекомендую ...
Может кому пригодится.

kpp
лейтенант
Сообщения: 613
Зарегистрирован: 2009-08-05 16:10:46
Откуда: Украина Днепропетровск-Киев
Контактная информация:

Re: Подскажите с tr

Непрочитанное сообщение kpp » 2011-05-04 17:29:48

Обычным awk такое не сделать?
Нет, ребята, я не гордый. Не загадывая вдаль, так скажу: зачем мне орден? Я согласен на медаль.

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 17:38:37

kpp писал(а):Обычным awk такое не сделать?
Уже не помню из каких соображений ставил gawk ....
Не копал в эту сторону, но скорее всего что можно, нужно глянуть есть ли в awk split и его синтаксис.

Ну и

Код: Выделить всё

cat ./file | awk '{....}' > ./tmp_file
В теории должно получится.

Аватара пользователя
kharkov_max
капитан
Сообщения: 1853
Зарегистрирован: 2008-10-03 14:56:40

Re: Подскажите с tr

Непрочитанное сообщение kharkov_max » 2011-05-04 17:55:54

kpp писал(а):Обычным awk такое не сделать?
А вот и ответ на Ваш вопрос.
В awk нет функции strftime, а она мне нужна для преобразования времени из timestamp.

А так, все должно работать и в awk.

kpp
лейтенант
Сообщения: 613
Зарегистрирован: 2009-08-05 16:10:46
Откуда: Украина Днепропетровск-Киев
Контактная информация:

Re: Подскажите с tr

Непрочитанное сообщение kpp » 2011-05-04 19:13:55

В обычном awk есть split и не обязательно делать

Код: Выделить всё

cat ./file | awk '{....}' > ./tmp_file
конструкция

Код: Выделить всё

awk '{....}' ./file > ./tmp_file
доступна и предпочтительна.
На счет функций, да, наверняка(нужно проверить) такой ф-ции нет, но это преобразование можно делать отдельно перед awk.
Нет, ребята, я не гордый. Не загадывая вдаль, так скажу: зачем мне орден? Я согласен на медаль.

Аватара пользователя
FreeBSP
майор
Сообщения: 2020
Зарегистрирован: 2009-05-24 20:20:19
Откуда: Москва

Re: Подскажите с tr

Непрочитанное сообщение FreeBSP » 2011-05-04 20:46:12

а пых/перл приколупать сюда не позволяют какие соображения?
да, менее православно чем шелл, но зато полно шустрых инструментов для обработки строк, оптимизации запросов и тд

кстати эфффективнее запихивать в базу пачки по 10-10000строк одним запросом,, чем на каждую строку выполнять запрос
суммарно по времени на обработку 1млн строк может выйти и эффективнее чем шелл.
Человек начинает получать первые наслаждения от знакомства с unix системами. Ему нужно помочь - дальше он сможет получать наслаждение самостоятельно ©
Ламер — не желающий самостоятельно разбираться. Не путать с новичком: ламер опасен и знает это!